C/C++中结构体与类成员变量在存储上的内存对齐问题

时间:2022-05-09 04:45:25

很多同学会遇到一个问题,为什么在结构中或类中定义的成员变量大小总和跟自己预期的可能会不一样,问题就在于系统在存储结构或类时涉及到一个内存对齐的问题,下面将讲解该问题。

因为结构体成员变量与类成员变量在存储上都涉及到内存对齐问题并且对齐规则都是一样的,所以下面主要演示结构体的内存对齐导致的现象。

成员变量在存储中的规则:

(1)结构体或类中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 

(2)结构体或类大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。

调用sizeof(Test)查看Test结构体内存大小占用情况,很多同学以为该结构体只占用4+8+1+4+2+1+2+1+1=24字节,其实并不然,该结构共占用40字节,为什么会这样呢?其中就涉及到内存对齐的问题。

struct Test{
int s1; //偏移量:0
double s2; //偏移量:4(前一个变量偏移量加上它所占用的大小0+4(int大小为4))由于该偏移量不是double自身变量的公倍数所以在前一个变量后面补齐12个字节使该变量的偏移量为16
char s3; //偏移量:24(前一个变量的偏移量+它(前一个变量)的大小 即16+8=24)
int s4; //偏移量:25(以此类推得到25)而25又不是自身的公倍数,所以继续补齐 即前一个变量后面加3个字节,所以该变量的偏移量是:28
float s5; //偏移量:32(以此类推得到32)刚好是float(2字节)的公倍数
char s6; //偏移量:34(以此类推得到34)也是char(1字节)的公倍数
short s7; //偏移量:35(以此类推得到35)补齐后为36
char s8; //偏移量:38(以此类推得到38)
char s9; //偏移量:39(以此类推得到39)
};
以上所有变量都已经遵循了规则1,结构体大小为最后一个变量的偏移量加上该变量的大小,也就是39+1=40字节。

遵循了规则1后还必须遵循规则2才能确定结构体最终大小,可以看到,40刚好都是以上所有变量大小的公倍数,规则2成立,如果规则2不成立的话,系统会在最后一个变量后面补齐字节数,使结构大小成为所有变量大小的整数倍。

int main(void){

std::cout << "Struct Test SumSize:" << sizeof(Test) << std::endl; //输出Struct Test SumSize:40
// printf("Struct Test SumSize:%d\n",sizeof(Test));
return 0;
}

C++类中成员变量内存对齐方式也遵循以上规则!计算方法也是一样的,这里就不做演示了。

本人也是刚学习C/C++不久,所以如果以上内容讲的有误的话,还请大大能指点出来。