作者jwliang (人類是很善良的)
看板C_and_CPP
標題[問題] stack與heap疑問
時間Fri Nov 29 20:06:41 2013
各位先進好,我有一個stack與heap的問題想請問,
通常stack與heap陸續配置的記憶體空間會逐步靠近,
就是說heap如果向下成長,stack就會向上成長,
借用此網站的程式結果:
http://wp.mlab.tw/?p=312 此網站的程式結果是如同我上述所說的那樣逐步靠近,
但我自己在ubuntu底下用gcc跑出來的結果如下:
-----------------------------------------------
程式碼:
int main(){
int a;
int b;
int *f=malloc(sizeof(int));
int *g=malloc(sizeof(int));
printf("a:%p\n",&a);
printf("b:%p\n",&b);
printf("f:%p\n",f);
printf("g:%p\n",g);
}
------------------------------------------------
結果:
a:0xbf9334c0
b:0xbf9334c4
f:0x9f7f008
g:0x9f7f018
------------------------------------------------
無論我怎麼看都不覺得stack的成長趨勢會與heap互相靠近,
也與上述網站所跑的成果有差異,請問是OS關係嗎?還是我哪裡想錯了,謝謝!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.160.20.149
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 20:19)
推 LPH66:stack 的成長是以函數呼叫為準, 而不是區域變數 11/29 21:16
→ LPH66:事實上編譯器可以把區域變數任意配置在目前這個 frame 上 11/29 21:16
→ LPH66:就沒有一定是哪個區域變數在下哪個區域變數在上了 11/29 21:17
您的意思是說,記憶體配置時如果有遇到碎片,compiler可以選擇把local變數隨機插在他想要的位置嗎?
其實我是想問Linux底下stack與heap之間成長的方向是否會相反,謝謝您的回答!
推 loveflames:而且WINDOWS的heap機制不是跟stack相反 11/29 21:34
→ loveflames:細節請看PEB 11/29 21:35
→ loveflames:另外,你需要透過debugger來學 11/29 21:36
→ jwliang:那請問一下,下列網站有兩張圖都是顯示會互相靠近 11/29 22:05
→ jwliang:顯示的結果也都是會互相靠近,是湊巧的嗎@@? 11/29 22:07
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 22:16)
→ damody:爬文吧 記得最近才有人講解過 11/29 22:39
推 loveflames:local變數不管怎麼放,都是放在stack frame,以X86架 11/29 22:44
→ loveflames:構來說就是以ebp為基準 11/29 22:44
恩 謝謝回答,我知道會放在stack frame中,但我想問的是方向。
→ jwliang:恩...我爬文的結果是unix系統是會互相靠近阿QQ 11/29 22:45
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 22:47)
推 loveflames:你真要測就用不同函式的local變數測 11/29 22:47
→ loveflames:不過學這個最好的辦法還是用debugger看記憶體及暫存器 11/29 22:48
→ loveflames:不建議用printf 11/29 22:48
推 Bencrie:寫個遞迴函數試試 11/29 22:51
推 loveflames:同函式local變數的位址跟stack方向無關,看compiler高 11/29 22:52
→ loveflames:興怎麼擺,不過不會跟parameter混一起放就是 11/29 22:53
推 loveflames:另外要注意的是static變數不是放stack 11/29 22:56
程式碼:
int main(){
int a;
int b;
int *f=malloc(sizeof(int));
int *g=malloc(sizeof(int));
a1();
printf("a:%p\n",&a);
printf("b:%p\n",&b);
printf("f:%p\n",f);
printf("g:%p\n",g);
}
int a1(){
int aa,aa2;
printf("aa:%p\n",&aa);
printf("aa:%p\n",&aa2);
}
執行結果:
aa:0xbfaf9968
aa:0xbfaf996c
a:0xbfaf9990
b:0xbfaf9994
f:0x9043008
g:0x9043018
恩...感覺他們還是一樣,不是會靠攏的,反而是一起往上成長!
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 23:00)
推 loveflames:學一下gdb吧,這個很好用的 11/29 22:59
→ jwliang:恩...gdb我會一些,但就是只是想了解書上說的相反方向成長 11/29 23:01
→ jwliang:是不是不一定一定是相反 11/29 23:02
→ purincess:(a, b) -> (aa, aa2)不就是反向的了.. 11/29 23:02
推 loveflames:aa位址比a跟b低啊 11/29 23:04
→ jwliang:問題是我先呼叫aa跟aa2的... 11/29 23:04
→ loveflames:正好就是因為a1的frame在main frame下方 11/29 23:05
→ loveflames:你先呼叫main,所以main local位址比較高 11/29 23:06
喔喔 對!那我知道了 謝謝了!
→ jwliang:恩~~那我要怎樣寫才可以顯示stack跟heap位址相反成長的感 11/29 23:06
→ jwliang:覺呢@@? 11/29 23:07
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 23:08)
→ purincess:現在這樣寫就有了啊 11/29 23:08
→ jwliang:恩 真的!謝謝了 11/29 23:10
推 loveflames:遞迴? 11/29 23:10
推 sunneo:你想要知道有沒有成長,大概除了讓他dirty還要看maps 12/11 04:19
→ sunneo:/proc/{pid}/maps , stack在最下面, heap在上面的位址 12/11 04:20
→ sunneo:malloc在超過256K時會改用mmap, 會在heap下面看到匿名區塊 12/11 04:21
→ sunneo:你可以用遞迴幾千次後印一下maps, 會看到效果的 12/11 04:24