2012-06-18 57 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

全局變量沒有在堆棧上分配;當它加載到內存中時它們是程序映像的一部分。由於不需要擔心堆棧幀(因此幀對齊),鏈接器可以將它們放在任何需要的位置。 –