结构体 sizeof

来源:百度知道 编辑:UC知道 时间:2024/06/23 18:17:27
union a
{
int a_int1;
double a_double;
int a_int2;
};

typedef struct
{
a a1;
char y;
} b;

class c
{
double c_double;
b b1;
a a2;
};
cout << "a = " << sizeof(a) << endl; //8
cout << "b = " << sizeof(b) << endl; //16
cout << "c = " << sizeof(c) << endl; //32
a,b的我能理解,可是为什么c的结果是32?
对齐模数是基本类型中最宽,应该是8吧
又b1的宽度是16,它存储的首地址不应是自身宽度的倍数么?不应是16么?
这样a2存储的首地址就应是32了呀,最后的结果感觉是40,当然这个结果被验证时错的,我在哪里出错了呢?麻烦解答一下!谢谢!
是我被误导了么?我参考的是:http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html
Win32平台下的微软C编译器(cl.exe for 80×86)的对齐策略:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal addin

对于字节对齐的问题,有几点需要注意理解:
(1)字节对齐是语言实现相关(编译器),而非C++特性
(2)对于cl.exe编译器:
A。 为了编译器寻址方便快捷,默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。
B。 还要注意的是,编译器会让结构体的大小是【最大成员】的整数倍。

基于上述原则我们就可以算出结构体的内存大小,当然这也是sizeof的实现原理。

【我发现你理解错误的地方了】:编译器看到的基本类型,而非使用了sizeof取大小的复合类型,再用这个例子解释一遍:

// 【最大成员是double 8字节,而非struct b 16字节,则整个struct的大小能被8整除】
class c
{
double c_double; // 偏移0
b b1; // b1.a1偏移8(sizeof(c_double))
// b1.y偏移8(sizeof(b1.a1))
a a2; // 【注意:】由于a2为double,需要放在为8倍数的偏移地址上(原则2.a)偏移8,而非sizeof(b1.y)
// a2占有8个字节,到此整个c的内存空间为32,也刚好为最大成员占有内存8的整数倍,不需要在尾部补齐字节
};

所以:
sizeof(c) = 32

如果我们再往后面添加两个成员,如下:
class c
{
double c_double; // 偏移0
b b1; // 同上
a a2; // 同上
int x; // 偏移8(sizeof(a2)) 【到此地址已经为c分配了32字节了】
short k; // 偏移4(sizeof(x)) 【到此c有36字节】
// k占有2个字节,为38,但由于不能被最大成员8整除,所以在编译器在尾部补上两个字节【原则2.b】