[問題] stack與heap疑問

看板C_and_CPP作者 (人類是很善良的)時間10年前 (2013/11/29 20:06), 編輯推噓11(11026)
留言37則, 7人參與, 最新討論串1/1
各位先進好,我有一個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)

11/29 21:16, , 1F
stack 的成長是以函數呼叫為準, 而不是區域變數
11/29 21:16, 1F

11/29 21:16, , 2F
事實上編譯器可以把區域變數任意配置在目前這個 frame 上
11/29 21:16, 2F

11/29 21:17, , 3F
就沒有一定是哪個區域變數在下哪個區域變數在上了
11/29 21:17, 3F
您的意思是說,記憶體配置時如果有遇到碎片,compiler可以選擇把local變數隨機插在他想要的位置嗎? 其實我是想問Linux底下stack與heap之間成長的方向是否會相反,謝謝您的回答!

11/29 21:34, , 4F
而且WINDOWS的heap機制不是跟stack相反
11/29 21:34, 4F

11/29 21:35, , 5F
細節請看PEB
11/29 21:35, 5F

11/29 21:36, , 6F
另外,你需要透過debugger來學
11/29 21:36, 6F

11/29 22:05, , 7F
那請問一下,下列網站有兩張圖都是顯示會互相靠近
11/29 22:05, 7F

11/29 22:06, , 8F
11/29 22:06, 8F

11/29 22:07, , 9F
顯示的結果也都是會互相靠近,是湊巧的嗎@@?
11/29 22:07, 9F
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 22:16)

11/29 22:39, , 10F
爬文吧 記得最近才有人講解過
11/29 22:39, 10F

11/29 22:44, , 11F
local變數不管怎麼放,都是放在stack frame,以X86架
11/29 22:44, 11F

11/29 22:44, , 12F
構來說就是以ebp為基準
11/29 22:44, 12F
恩 謝謝回答,我知道會放在stack frame中,但我想問的是方向。

11/29 22:45, , 13F
恩...我爬文的結果是unix系統是會互相靠近阿QQ
11/29 22:45, 13F
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 22:47)

11/29 22:47, , 14F
你真要測就用不同函式的local變數測
11/29 22:47, 14F

11/29 22:48, , 15F
不過學這個最好的辦法還是用debugger看記憶體及暫存器
11/29 22:48, 15F

11/29 22:48, , 16F
不建議用printf
11/29 22:48, 16F

11/29 22:51, , 17F
寫個遞迴函數試試
11/29 22:51, 17F

11/29 22:52, , 18F
同函式local變數的位址跟stack方向無關,看compiler高
11/29 22:52, 18F

11/29 22:53, , 19F
興怎麼擺,不過不會跟parameter混一起放就是
11/29 22:53, 19F

11/29 22:56, , 20F
另外要注意的是static變數不是放stack
11/29 22:56, 20F
程式碼: 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)

11/29 22:59, , 21F
學一下gdb吧,這個很好用的
11/29 22:59, 21F

11/29 23:01, , 22F
恩...gdb我會一些,但就是只是想了解書上說的相反方向成長
11/29 23:01, 22F

11/29 23:02, , 23F
是不是不一定一定是相反
11/29 23:02, 23F

11/29 23:02, , 24F
(a, b) -> (aa, aa2)不就是反向的了..
11/29 23:02, 24F

11/29 23:04, , 25F
aa位址比a跟b低啊
11/29 23:04, 25F

11/29 23:04, , 26F
問題是我先呼叫aa跟aa2的...
11/29 23:04, 26F

11/29 23:05, , 27F
正好就是因為a1的frame在main frame下方
11/29 23:05, 27F

11/29 23:06, , 28F
你先呼叫main,所以main local位址比較高
11/29 23:06, 28F
喔喔 對!那我知道了 謝謝了!

11/29 23:06, , 29F
恩~~那我要怎樣寫才可以顯示stack跟heap位址相反成長的感
11/29 23:06, 29F

11/29 23:07, , 30F
覺呢@@?
11/29 23:07, 30F
※ 編輯: jwliang 來自: 118.160.20.149 (11/29 23:08)

11/29 23:08, , 31F
現在這樣寫就有了啊
11/29 23:08, 31F

11/29 23:10, , 32F
恩 真的!謝謝了
11/29 23:10, 32F

11/29 23:10, , 33F
遞迴?
11/29 23:10, 33F

12/11 04:19, , 34F
你想要知道有沒有成長,大概除了讓他dirty還要看maps
12/11 04:19, 34F

12/11 04:20, , 35F
/proc/{pid}/maps , stack在最下面, heap在上面的位址
12/11 04:20, 35F

12/11 04:21, , 36F
malloc在超過256K時會改用mmap, 會在heap下面看到匿名區塊
12/11 04:21, 36F

12/11 04:24, , 37F
你可以用遞迴幾千次後印一下maps, 會看到效果的
12/11 04:24, 37F
文章代碼(AID): #1Ic8DL4S (C_and_CPP)