关于32位和64位下面类的默认内存对齐规则

liups 2019-11-25 08:40:50
经过本人测试,好象与网上很多人说的不一样,默认对齐应该是和指针长度一样而不是很多人说的int长度一样,有请大神讲解一下。
测试代码如下:
 //program 12.7.1.cpp const成员和引用成员
#include <iostream>
using namespace std;
int f;
class CDemo {
private :
const int num; //常量型成员变量
int & ref; //引用型成员变量
int value;
public:
CDemo( int n):num(n),ref(f),value(4)
{
}
};
int main(){
int*p;
cout << sizeof(CDemo) << endl;
cout << sizeof(int) << endl;
cout << sizeof(p) << endl;
system("pause");
return 0;
}
...全文
864 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
liups 2019-12-01
  • 打赏
  • 举报
回复
引用 24 楼 mby2015 的回复:
我回复了 也没获得10分啊
抱歉了,虽然我通常是给大家平分,这主题是感觉有网友真的对我帮助很大,所以全给他了
mby2015 2019-12-01
  • 打赏
  • 举报
回复
我回复了 也没获得10分啊
BUG maker何何何 2019-11-29
  • 打赏
  • 举报
回复
这个需要看你使用的是哪种操作系统
Zxy0918520 2019-11-28
  • 打赏
  • 举报
回复
引用 21 楼 liups 的回复:
[quote=引用 19 楼 Zxy0918520 的回复:] 不是和你说了吗,,非静态的引用成员在实现类似于指针,
说得对!这句话是重点[/quote]嗯嗯,不说了,太晚了,睡了
liups 2019-11-28
  • 打赏
  • 举报
回复
引用 19 楼 Zxy0918520 的回复:
不是和你说了吗,,非静态的引用成员在实现类似于指针,
说得对!这句话是重点
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 17 楼 Zxy0918520 的回复:
[quote=引用 15 楼 liups 的回复:][quote=引用 14 楼 Zxy0918520 的回复:] 哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
但是sizeof(int&)结果为4!sizeof(p)才是8![/quote]更正。一下,那个实现里。引用类型的非静态数据成员实现上大概和指针相同,所以。sizeof类里面的引用当成了指针,指针是8其他两个1对齐到8,至于sizeof(p)是8因为是指针。。[/quote] 你这里的说法应该是正确的了!把那个引用符号去掉不论32位还是64位就都是12了。 小结一下: 1、对齐是以最大那个的长度来的; 2、类里面的引用和外面的引用是不一样的,sizeof的结果是和指针一样的。 再放一个测试程序:
//program 12.7.1.cpp const成员和引用成员
#include <iostream>
using namespace std;
char f;
class CDemo
{
private:
	const char num; //常量型成员变量
	char ref;		//引用型成员变量
	char value;

public:
	CDemo(int n) : num(n), ref(f), value(4)
	{
	}
};
int main()
{
	char *p;
	cout << sizeof(CDemo) << endl;
	cout << sizeof(int) << endl;
	cout << sizeof(char) << endl;
	cout << sizeof(char&) << endl;
	cout << sizeof(p) << endl;
	system("pause");
	return 0;
}
其结果是: 3 4 1 1 8
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
不是和你说了吗,,非静态的引用成员在实现类似于指针,
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 17 楼 Zxy0918520 的回复:
[quote=引用 15 楼 liups 的回复:][quote=引用 14 楼 Zxy0918520 的回复:] 哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
但是sizeof(int&)结果为4!sizeof(p)才是8![/quote]更正。一下,那个实现里。引用类型的非静态数据成员实现上大概和指针相同,所以。sizeof类里面的引用当成了指针,指针是8其他两个1对齐到8,至于sizeof(p)是8因为是指针。。[/quote] 指针是8没错,但是类里面没有指针!指针是因为我的推测才加上的,不过没放到类里面,只是输出sizeof(p)用于查看
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
引用 15 楼 liups 的回复:
[quote=引用 14 楼 Zxy0918520 的回复:] 哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
但是sizeof(int&)结果为4!sizeof(p)才是8![/quote]更正。一下,那个实现里。引用类型的非静态数据成员实现上大概和指针相同,所以。sizeof类里面的引用当成了指针,指针是8其他两个1对齐到8,至于sizeof(p)是8因为是指针。。
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 15 楼 liups 的回复:
[quote=引用 14 楼 Zxy0918520 的回复:] 哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
但是sizeof(int&)结果为4!sizeof(p)才是8![/quote] sizeof(type&)和sizeof(type)是一样的!
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 14 楼 Zxy0918520 的回复:
哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
但是sizeof(int&)结果为4!sizeof(p)才是8!
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
哪有什么默认对齐规则啊,标准不是说的。很清楚了吗,至于你第一个为什么是24是因为class里面有一个引用类型是,sizeof引用类型就是引用类型为8还有两个char加起来应该为10不过标准要求对齐到接近的类型,所以两个1分别被拓展到最大的sizeof(char&),所以两个1都被拓展到8,所以3个8为24,这跟指针有什么关系,顺便贴一段sizeof的介绍。 8.5.2.3 sizeof 2 When applied to a reference or a reference type, the result is the size of the referenced type.
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 12 楼 Zxy0918520 的回复:
不是很懂你还有哪里不明白的
默认内存对齐规则到底有没有,如果有是什么?或者说是否我猜测的以指针为准
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
不是很懂你还有哪里不明白的
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 8 楼 mymtom 的回复:
一般按照数据自己的宽度进行对齐 下面的程序redhat编译为64位程序的话,输出为 0 4 0 8

#include <stddef.h>
#include <stdio.h>

struct s1 {
    char  c;
    int   n;
};

struct s2 {
    char  c;
    void *p;
};

int
main(int argc, char *argv[])
{
    printf("%d\n", (int)offsetof(struct s1, c));
    printf("%d\n", (int)offsetof(struct s1, n));
    printf("%d\n", (int)offsetof(struct s2, c));
    printf("%d\n", (int)offsetof(struct s2, p));
    return 0;
}
不是很赞同。 我把测试程序改得更极端了一点:
//program 12.7.1.cpp const成员和引用成员
#include <iostream>
using namespace std;
char f;
class CDemo
{
private:
	const char num; //常量型成员变量
	char &ref;		//引用型成员变量
	char value;

public:
	CDemo(int n) : num(n), ref(f), value(4)
	{
	}
};
int main()
{
	char *p;
	cout << sizeof(CDemo) << endl;
	cout << sizeof(int) << endl;
	cout << sizeof(char) << endl;
	cout << sizeof(p) << endl;
	system("pause");
	return 0;
}
测试过turbo C++,mingw64,mingw,MS VC6.0和2010,发现默认都是按是指针长度对齐的。在64位下面程序输出是: 24 4 1 8
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
不是。不过挺权威,standard paper下面的内容是摘自标准里面
liups 2019-11-27
  • 打赏
  • 举报
回复
引用 5 楼 Zxy0918520 的回复:
这个需要看你使用的是哪种操作系统,对象是子对象还是一个完整的对象 https://en.cppreference.com/w/cpp/language/types fundmental types/ data model Data models The choices made by each implementation about the sizes of the fundamental types are collectively known as data model. Four data models found wide acceptance: 32 bit systems: LP32 or 2/4/4 (int is 16-bit, long and pointer are 32-bit) Win16 API ILP32 or 4/4/4 (int, long, and pointer are 32-bit); Win32 API Unix and Unix-like systems (Linux, Mac OS X) 64 bit systems: LLP64 or 4/4/8 (int and long are 32-bit, pointer is 64-bit) Win64 API LP64 or 4/8/8 (int is 32-bit, long and pointer are 64-bit) Unix and Unix-like systems (Linux, Mac OS X) Other models are very rare. For example, ILP64 (8/8/8: int, long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g. Unicos on Cray). standard paper Object types have alignment requirements (6.7.1, 6.7.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (10.6.2). 2 A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to alignof(std::max_align_t) (21.2). The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. [ Example: struct B { long double d; }; struct D : virtual B { char c; }; When D is the type of a complete object, it will have a subobject of type B, so it must be aligned appropriately for a long double. If D appears as a subobject of another object that also has B as a virtual base class, the B subobject might be part of a different subobject, reducing the alignment requirements on the D subobject. —end example ] The result of the alignof operator reflects the alignment requirement of the type in the complete-object case.
这个网址是Cpp的标准吧?
mymtom 2019-11-27
  • 打赏
  • 举报
回复
一般按照数据自己的宽度进行对齐
下面的程序redhat编译为64位程序的话,输出为
0
4
0
8

#include <stddef.h>
#include <stdio.h>

struct s1 {
char c;
int n;
};

struct s2 {
char c;
void *p;
};

int
main(int argc, char *argv[])
{
printf("%d\n", (int)offsetof(struct s1, c));
printf("%d\n", (int)offsetof(struct s1, n));
printf("%d\n", (int)offsetof(struct s2, c));
printf("%d\n", (int)offsetof(struct s2, p));
return 0;
}
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
附上一段代码

#include <iostream>
struct A
{
    const long double a;
};

struct B:virtual A
{
    char s;
};

struct C
{
    char s;
};

int main()
{
    std::cout<<sizeof(A)<<std::endl;

    std::cout<<sizeof(std::declval<const void*>())<<std::endl;

    std::cout<<sizeof(B)<<std::endl;

     std::cout<<sizeof(C)<<std::endl;

    return 0;
}

测试连接: https://gcc.godbolt.org/z/nHfRvX
Zxy0918520 2019-11-27
  • 打赏
  • 举报
回复
这个需要看你使用的是哪种操作系统,对象是子对象还是一个完整的对象 https://en.cppreference.com/w/cpp/language/types fundmental types/ data model Data models The choices made by each implementation about the sizes of the fundamental types are collectively known as data model. Four data models found wide acceptance: 32 bit systems: LP32 or 2/4/4 (int is 16-bit, long and pointer are 32-bit) Win16 API ILP32 or 4/4/4 (int, long, and pointer are 32-bit); Win32 API Unix and Unix-like systems (Linux, Mac OS X) 64 bit systems: LLP64 or 4/4/8 (int and long are 32-bit, pointer is 64-bit) Win64 API LP64 or 4/8/8 (int is 32-bit, long and pointer are 64-bit) Unix and Unix-like systems (Linux, Mac OS X) Other models are very rare. For example, ILP64 (8/8/8: int, long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g. Unicos on Cray). standard paper Object types have alignment requirements (6.7.1, 6.7.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (10.6.2). 2 A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to alignof(std::max_align_t) (21.2). The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. [ Example: struct B { long double d; }; struct D : virtual B { char c; }; When D is the type of a complete object, it will have a subobject of type B, so it must be aligned appropriately for a long double. If D appears as a subobject of another object that also has B as a virtual base class, the B subobject might be part of a different subobject, reducing the alignment requirements on the D subobject. —end example ] The result of the alignof operator reflects the alignment requirement of the type in the complete-object case.
加载更多回复(4)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧