一下均為網路上收集的資料:
1、所謂在編譯期間分配空間指的是靜態分配空間(相對於用new動態申請空間),如全域性變數或靜態變數(包括一些複雜型別的常量),它們所需要的空間大小可以 明確計算出來,並且不會再改變,因此它們可以直接存放在可執行檔案的特定的節裡(而且包含初始化的值),程式執行時也是直接將這個節載入到特定的段中,不 必在程式執行期間用額外的**來產生這些變數。
其實在執行期間再看「變數」這個概念就不再具備編譯期間那麼多的屬性了(諸如名稱,型別,作用域,生存期等等),對應的只是一塊記憶體(只有首址和大小), 所以在執行期間動態申請的空間,是需要額外的**維護,以確保不同變數不會混用記憶體。比如寫new表示有一塊記憶體已經被占用了,其它變數就不能再用它了; 寫delete表示這塊記憶體自由了,可以被其它變數使用了。(通常我們都是通過變數來使用記憶體的,就編碼而言變數是給記憶體塊起了個名字,用以區分彼此)
記憶體申請和釋放時機很重要,過早會丟失資料,過遲會耗費記憶體。特定情況下編譯器可以幫我們完成這項複雜的工作(增加額外的**維護記憶體空間,實現申請和釋 放)。從這個意義上講,區域性自動變數也是由編譯器負責分配空間的。進一步講,記憶體管理用到了我們常常掛在嘴邊的堆和棧這兩種資料結構。
最後對於「編譯器分配空間」這種不嚴謹的說法,你可以理解成編譯期間它為你規劃好了這些變數的記憶體使用方案,這個方案寫到可執行檔案裡面了(該檔案中包含若干並非出自你大腦衍生的**),直到程式執行時才真正拿出來執行。
2、編譯其實只是乙個掃瞄過程,進行詞法語法檢查,**優化而已,編譯程式越好,程式執行的時候越高效。 我想你說的「編譯時分配記憶體」是指「編譯時賦初值」,它只是形成乙個文字,檢查無錯誤,並沒有分配記憶體空間。
當你執行時,系統才把程式匯入記憶體。乙個程序(即執行中的程式)在主要包括以下五個分割槽: 棧、堆、bss、data、code
**(編譯後的二進位制**)放在code區,**中生成的各種變數、常量按不同型別分別存放在其它四個區。系統依照**順序執行,然後依照**方案改變或呼叫資料,這就是乙個程式的執行過程。
3、編譯時分配記憶體 --------------- 編譯時是不分配記憶體的。此時只是根據宣告時的型別進行佔位,到以後程式執行時分配記憶體才會正確。所以宣告是給編譯器看的,聰明的編譯器能根據宣告幫你識別錯誤。
執行時分配記憶體 --------------- 這是對的,執行時程式是必須調到「記憶體」的。因為cpu(其中有多個暫存器)只與記憶體打交道的。程式在進入實際記憶體之前要首先分配物理記憶體。
編譯過程 -------------- 只能簡單說一下,因為如果要詳細的話,就是一本書了《編譯原理》。編譯器能夠識別語法,資料型別等等。然後逐行逐句檢查編譯成二進位制資料的obj檔案,然後再由鏈結程式將其鏈結成乙個exe檔案。此時的程式是以exe檔案的形式存放在磁碟上。
執行過程 -------------- 當執行這個exe檔案以後,此程式就被載入到記憶體中,成為程序。此時一開始程式會初始化一些全域性物件,然後找到入口函式(main()或者winmain()),就開始按程式的執行語句開始執行。此時需要的記憶體只能在程式的堆上進行動態增加/釋放了。
inta =0
; //
全域性初始化區
char
*p1;
//全域性未初始化區
intmain()
分類: c++
C 關於書上說的「編譯的時候分配記憶體」
1 所謂在編譯期間分配空間指的是靜態分配空間 相對於用new動態申請空間 如全域性變數或靜態變數 包括一些複雜型別的常量 它們所需要的空間大小可以 明確計算出來,並且不會再改變,因此它們可以直接存放在可執行檔案的特定的節裡 而且包含初始化的值 程式執行時也是直接將這個節載入到特定的段中,不 必在程式...
轉 關於書上說的「編譯的時候分配記憶體」
不是編譯鏈結時就要占用記憶體,而是,在編譯時就知道應該占用多大記憶體,而不需要在執行時才知道需要占多大記憶體,且哪些資料儲存在哪個位置,也是編譯時確定的。如果是執行時才知道怎麼樣,那麼一定是執行時通過某種判斷才知道,這樣,必定會影響效率!一下均為網路上收集的資料 1 所謂在編譯期間分配空間指的是靜態...
變數的記憶體單元是編譯器在編譯時候分配的
所謂在編譯期間分配空間指的是靜態分配空間 相對於用new動態申請空間 如全域性變數或靜態變數 包括一些複雜型別的常量 它們所需要的空間大小可以明確計算出來,並且不會再改變,因此它們可以直接存放在可執行檔案的特定的節裡 而且包含初始化的值 程式執行時也是直接將這個節載入到特定的段中,不必在程式執行期間...