2015-10-21 49 views
0
int main(int argc , char *argv[]) 
{ 

int value = 5; 
char buffer_one[8] , buffer_two[8]; 

strcpy(buffer_one,"one"); 
strcpy(buffer_two,"two"); 
printf("[BEFORE] buffer_two is at %p and containt \'%s\' \n ",buffer_two,buffer_two); 

printf("[BEFORE] buffer_one is at %p and containt \'%s\' \n ",buffer_one,buffer_one); 
printf("[BEFORE] value is at %p and is %d (0x%08x)\n",&value,value,value); 

} 

我得到了這樣的結果:變量低於地址指針的地址?

[BEFORE] buffer_two is at 0x7ffd75d46720 and containt 'two' 
[BEFORE] buffer_one is at 0x7ffd75d46710 and containt 'one' 
[BEFORE] value is at 0x7ffd75d4670c and is 5 (0x00000005) 

正如你可以看到buffer_two的住址是高於buffer_one(因爲它被推堆和和堆上升到更高的不會忽略)這裏的一切是好。

我不明白爲什麼Value變量的地址小於兩者,我認爲它必須更高,因爲變量存儲在堆棧中!並且堆棧比堆堆有更高的地址!

任何一個可以幫助PLZ

+5

你爲什麼認爲'buffer_one'和'buffer_two'會堆在堆上,而不是堆棧中?畢竟他們都是本地/自動變量。 – Kninnug

+1

'value','buffer_one'和'buffer_two'都在堆棧中。 'value'在最低地址,然後我們有'buffer_one',在最高地址我們有'buffer_two'。哪裏有問題 ?順便說一句:編譯器可以按任意順序自由地將變量排列在堆棧上。 –

+1

'棧的地址高於堆' - 是什麼讓你覺得呢?您可能在某處曾經觀察過這種情況,但該標準對此沒有任何說明,它們可以自由地位於地址空間的任何位置。此外,挑剔,但它是「地址」和「包含」,而不是「地址」和「containt」。 – szczurcio

回答

0

因爲所有這三個變量的函數中定義的,他們都住在堆棧中。堆棧通常會向下增長,所以它看起來像buffer_two的空間首先被壓入堆棧,然後是8個填充字節,然後是buffer_one,然後是value。這就是說,如何在堆棧上放置變量是實現定義的,並且在做出看起來不相關的代碼更改時,在相同的實現中可能會有所不同。

例如,在我的系統該代碼輸出以下:

[BEFORE] buffer_two is at 0xbfb16110 and containt 'two' 
[BEFORE] buffer_one is at 0xbfb16118 and containt 'one' 
[BEFORE] value is at 0xbfb16120 and is 5 (0x00000005) 

在這種情況下,變量被放置在堆棧上以相反的順序,並且不帶8字節的填充。

+1

「變量如何放置在堆棧上」不是實現定義的。 C標準根本沒有提到堆棧,它只需要本地變量的工作。 –

0

沒有要求編譯器以任何特定的順序存儲單獨的對象(無論該存儲是來自堆棧,堆還是某些其他內存段)。它不必按照你宣佈的順序排列,也不必在記憶中相鄰。

struct成員必須按照聲明順序排列,但它們可能相鄰或不相鄰;成員之間可能會有「填充」字節,這也是由於對齊要求。