c/c++内存对齐总结

本文详细介绍了C/C++中的内存对齐规则,通过实例分析了不同平台和编译器下结构体内存布局的影响。内容包括:内存对齐的基本概念、内存对齐规则、如何通过#pragma pack指定对齐系数,以及不同对齐系数对结构体总长度的影响。此外,还列举了多个场景案例来帮助理解内存对齐的重要性。
摘要由CSDN通过智能技术生成
1、引言
对于结构体来经常会涉及到内存对齐问题,如下面代码所示:
#include <stdio.h>


struct Test
{
short x1;   
char x2;    
float x3;   
char x4;     
};


int main(void)
{
struct Test t;
//printf("0x%p\n", &t.x1);
//printf("0x%p\n", &t.x2);
//printf("0x%p\n", &t.x3);
//printf("0x%p\n", &t.x4);




printf("sizeof(char) = %lu", sizeof(char));
printf("sizeof(char) = %lu", sizeof(int));
printf("sizeof(char) = %lu", sizeof(short));
printf("%lu\n", sizeof(t));


return 0;

}

执行该段代码可以得到以下结果:



我是在VS2015下进行的编译,可以得到各自变量所占的长度以及结构体所占长度,一般按照字面来说,结构体所占字节数应该为:
2+1+4+1 = 8,但是事实上该结构体最终的长度为12,此时就涉及到内存对齐的问题;

2、内存对齐规则
不同的平台的特定编译器都有自己默认的“对齐系数”。我们可以强制指定对齐系数,通过#pragma pack(k), k = 1,2,4,8,16等;
也可以通过#pragme pack()取消已经指定的对齐系数,对齐的规则如下:
规则一:
struct或者union中,起始的offset为0,对齐系数为#pragma pack指定的和自身所占字节数中较小的那个值进行对齐,如下代码所示:
#pragma pack(4)


struct Test
{
short x1; 
char x2;   
float x3;   
char x4;     
};



现在已经占了9字节的长度,但是实际上所占长度为12,这为什么呢?我们看内存对齐规则二。


规则二:
在struct或者union元素对齐后,struct或者union整体也要进行对齐操作,对齐将按照,#pragma pack和struct或者union中成员中最大数据成员中较小的那个进行;
则对于以上的例子来说,pragma pack为4,结构体中最大数据成员长度也为4,则结构提整体以4位对齐系数进行对齐,已经有9个字节,则补3字节为12字节。所以整个结构体长度为12。


3、其他对场景举例
* 场景一:
#pragma pack(1)


struct Test
{
short x1; 
char x2;   
float x3;   
char x4;     
};


整体struct对齐系数为:pragma pack(1) 和 float中较小者为 1;
则整体结构体所占长度为8.


*场景二:
#pragma pack(8)


struct Test
{
short x1; 
char x2;   
float x3;   
char x4;     
};


现在所占字节为:9
整体struct对齐系数为:pragma pack(8) 和 float中较小者为 4;
则整体结构体所占长度为12。


4、结尾
内存对齐对于c/c++程序员来说是必须要掌握的一个点,也是各种面试和笔试中常考的点,至此将内存对齐做了一个总结,以备后续查阅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值