C语言用_Alignas指定对齐后为何出现内存填充?
关于C语言内存对齐与
_Alignas的疑问解答 让我一步步帮你理清这两个困惑点:
1. 为什么cz后面会出现内存填充?
首先要明确栈内存的增长方向:大部分系统中,栈是从高地址向低地址分配内存的。你代码里变量的声明顺序是dx→ca→cx→dz→cb→cz,但实际在栈中的地址顺序是反过来的:dx(最高地址)→ca→cx→dz→cb→cz(最低地址)。
你看到的“cz后面的填充”,其实是在cb和cz之间的空间——因为_Alignas(double)要求cz的地址必须是8字节的倍数(double类型的对齐要求)。而cb的地址是0x28ff0f,它的下一个可用地址(0x28ff10)并不满足8字节对齐,所以编译器必须在cb和cz之间插入填充字节,把cz“推”到符合对齐要求的地址(0x28ff08,这是离0x28ff10最近的、更低的8字节对齐地址)。
2. 为什么填充是6字节,而不是7字节?
这里要区分两个概念:对齐要求和变量大小。_Alignas(double)只是要求cz的地址是8字节的倍数,并没有改变cz本身的大小(它还是1字节的unsigned char)。
我们来算一下:
cb的地址是0x28ff0f,它占用1字节,所以下一个未使用的地址是0x28ff10。- 我们需要找到比
0x28ff10小的最大的8字节对齐地址:0x28ff08(因为0x28ff08 % 8 = 0)。 - 从
0x28ff08到0x28ff0f之间共有7个地址:0x28ff08(cz本身) + 6个填充地址(0x28ff09到0x28ff0e),正好到0x28ff0f(cb的地址)。
如果填充7字节的话,cz的地址会变成0x28ff07,这个地址不是8的倍数(0x28ff07 %8 =7),不符合_Alignas(double)的要求,所以编译器不会这么做。
总结一下:_Alignas的作用是保证变量的起始地址符合指定的对齐边界,为了满足这个要求,编译器会在栈上的变量之间插入必要的填充字节,填充的数量由目标地址的对齐要求和前一个变量的位置决定。
内容的提问来源于stack exchange,提问作者AlexQualcosa
相关产品推荐
相关产品推荐

