2010-12-13 48 views
2

這一直困擾着我,現在很長一段時間:可以說,我有一個函數:C++:函數變量聲明,它如何在內部工作?

void test(){ 
    int t1, t2, t3; 
    int t4 = 0; 
    int bigvar[10000]; 
    // do something 
} 

如何計算機處理的變量內存分配?

我一直認爲變量空間保存在計算機將讀取的.exe中,這是正確的嗎?但據我所知,bigvar陣列沒有采取10000 int元素空間在.exe,因爲它未初始化。那麼當我調用函數時,它的內存分配如何工作?

+0

該exe文件存儲在_disk_中,編譯後的代碼存儲在那裏。但是當它被執行時,它會從_processor_單元獲取內存。磁盤中的字節不對應變量所需的字節。 – 2010-12-13 13:38:56

+0

http://stackoverflow.com/questions/556714/how-does-the-stack-work-in-assembly-language – karlphillip 2010-12-13 13:41:17

回答

9

這些局部變量通常使用處理器的stack來實現。這意味着編譯器唯一需要做的就是計算每個變量的大小,並將它們加在一起。總和是在函數入口處改變堆棧指針的數量,並在退出時改變。然後每個變量以相對偏移量訪問堆棧中的該塊內存。

您的代碼,在Linux下編譯時,結束了在x86彙編看起來像這樣:

test: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $40016, %esp 
     movl $0, -4(%ebp) 
     leave 
     ret 

在上面,不斷的$ 40016是需要的4個32位整數t1, t2, t3t4的空間,而其餘的40000個字節佔據了10000個元素的陣列bigvar

+0

很好的解釋! – Nawaz 2010-12-13 14:10:58

0

除了一些注意事項外,我無法對已經說過的內容添加太多內容。實際上,您可以將局部變量放入可執行文件中,並將它們分配到數據段(並初始化)而不是堆棧段中。爲此,請將它們聲明爲static。但是,然後所有的函數調用將在堆棧中共享相同的變量,每次調用都會創建一組新的變量。這可能會導致很多麻煩,當函數被多個線程同時調用或者存在遞歸時(嘗試設想)。這就是爲什麼大多數語言對本地變量使用堆棧並且很少使用static

0

在一些舊的編譯器上,我遇到了靜態分配數組的行爲。這意味着它在加載程序時爲其留出內存,並在此之後使用該空間。這種行爲是不安全的(見謝爾蓋的答案),我也不期望它根據標準被允許,但我在野外遇到它。 (我沒有記住它是什麼編譯器。)

大多數情況下,本地變量保留在堆棧上,以及返回地址和所有其他東西。這意味着未初始化的值可能包含敏感信息。這也包括數組,根據unwind的答案。

另一個有效的實現是在堆棧中找到的變量是一個指針,並且編譯器在引擎蓋下執行分配和釋放(推測是以一種異常安全的方式)。這將節省堆棧空間(在程序啓動之前必須分配堆棧空間,並且x86架構不能輕鬆擴展),並且對於C標準VLA(可變長度陣列,又名窮人std :: vector)也非常有用

相關問題