2012-06-18 64 views
2

我想问一下64位ubuntu Linux中的内存分配问题。64位机内存分配

我有以下代码

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) { 
    char buffer_one[8], buffer_two[8]; 

    printf("Size of char: %u\n", sizeof(char)); 

    printf("Buffer_two is at %p\n", buffer_two); 
    printf("Buffer_one is at %p\n", buffer_one); 
} 

,并在运行时,下面的结果显示了

$ ./sizeofchar 
Size of char: 1 
Buffer_two is at 0x7fff98069910 
Buffer_one is at 0x7fff98069900 

我的问题是,即使char类型的大小为1个字节,我以为(请纠正我,如果我在这里错了)Buffer_twoBuffer_one被分配彼此相邻,为什么Buffer_twoBuffer_one内存地址分配16个字节。

+2

这是一个严格的实现细节。一个编译器可以自由地分配一个局部变量在它选择的任何地址,你的程序不应该依赖这个地址是任何特定的。 –

+0

我愿意打赌这是一个16字节对齐的优化 –

+0

@Als谢谢,我不是想要依靠这个地址。我只是好奇,如果有特别的理由。 – Wins

回答

6

这是编译器相关的行为。由于这些是堆栈分配的缓冲区(实际上与内存分配无关),所以编译器如何在堆栈中布局堆栈局部变量。你可以玩这个,但我猜想所有的数组都是以16字节的增量分配在堆栈上,这是出于某种原因。

如果你看看反汇编,你可以看到在栈帧中变量被设置为的位置。我有一个预感,char[2]char[15]都在堆栈帧结束了16个字节。为什么,我不完全确定。但我可以补充说的是,x64 ABI指定堆栈始终是16字节对齐的,这种分配方式可以很容易地保证。

+1

在任何调用指令之前,堆栈指针应该在16个字节对齐。我不知道为什么GCC也对齐堆栈数组。可能有些libc函数是SSE优化的,需要在16字节边界上对齐的数据,但如果这些数组是全局或静态的,则GCC不再将它们对齐。英特尔的'icc'放置这些阵列没有间隙。去搞清楚。 –

+0

@Jonathon Reinhart对,'char [2]'和'char [15]'是正确的,它们都在堆栈帧中占用16个字节。不过,我也意识到,对于全局变量,它们被分配在一起。含义为'char [2]'和'char [15]'的全局变量分别分配2个和15个字节。任何想法为什么? – Wins

+1

全局变量没有在堆栈上分配;当它加载到内存中时它们是程序映像的一部分。由于不需要担心堆栈帧(因此帧对齐),链接器可以将它们放在任何需要的位置。 –