结构体内存对齐详解

平时做题对内存对齐有很多疑惑,网上的说法也有很多,而且都给出了例子,看起来好像都是对的,但它们有时却又自相矛盾。


今天花了一下午时间总结一下:

首先详解Linux系统下的内存对齐

笔者以32位的小红帽系统和64位的乌班图系统来做详细的测试:


我们先不讲理论,法则,先来看一个例子(32位小红帽系统下):



大家看一下这样应该是输出多少? 我之前认为应该是24,因为我认为结构体应该按结构体内字节数占用最大的成员对齐,这里最大的为double,占8个字节,所以对齐方式应该是

int a;  //4个字节

int c;  //4个字节

double bb;  //8个字节

char d;  //占一个字节,但因为内存对齐,这里应补齐为8个字节,所以d变量占8个字节,这是我初始的理解,但这是我的一厢情愿,程序实际测试结果为20;



这是因为什么呢?

因为32位的Linux系统中gcc编译器的对齐模数最大为4,所以这个结构体的实际内存对齐模型为:

int a;  //4个字节

int c;  //4个字节

double bb;  //8个字节

char d;  //占一个字节,但因为内存对齐,这里应补齐为4个字节,

所以共占20个字节。

为什么这里的最大对其模数为4呢,因为第一查阅了资料,第二笔者用#pragma pack(n)  宏定义做了测试

第一设置n为2,即对齐模数设置为了2,这时程序输出的结果 为18;因为图片挺大的,就不放了,这时的内存对齐模型为

int a;  //4个字节
int c;  //4个字节
double bb;  //8个字节
char d;  //占一个字节,但因为内存对齐模数设置成了2,这里应补齐为2个字节,

所以这样就是18个字节了,

这时再将n设置为8,程序输出结果还是20,并没有按设想的是24,


笔者这时又用64位的乌班图系统测试


程序一样,不设置对齐模数

这时程序输出为24,因为乌版图是64位的,这里自动按了8字节对齐,所以为24.

这下关于结构体内存对齐i很清晰明了了,

就是32位的系统内存对齐模数最大为4,

64位的系统内存对齐模数为8,这仅是在Linux系统测试的结果。


下面继续讲解结构体A内又包含了一个结构体B,这时结构体A所占的内存为多大呢?这还是和系统的位数有关。


这时的结果为24,


但在乌班图系统内为28,因为结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

这里在乌班图内结构体A内的int a;占8个字节,因为cc里面有double,而在小红帽里,对齐模数为4,所以int 只占4个字节,cc从第4个字节开始存储。


测试完了,各位读者应该有一个清晰明了的观点了吧!


下面列出查找资料时的总结:

三准则:

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.



另外在C++中,一个空类和空结构体是占一个字节的空间的。在C语言中,空结构体不占空间。



  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值