1. 程式人生 > >編譯期記憶體分配

編譯期記憶體分配

 

 所謂在編譯期間分配空間指的是靜態分配空間(相對於用new動態申請空間),如全域性

變數或靜態變數(包括一些複雜型別的常量),它們所需要的空間大小可以 明確計算

出來,並且不會再改變,因此它們可以直接存放在可執行檔案的特定的節裡(而且包含

初始化的值),程式執行時也是直接將這個節載入到特定的段中,不 必在程式執行期

間用額外的程式碼來產生這些變數。


其實在執行期間再看“變數”這個概念就不再具備編譯期間那麼多的屬性了(諸如名稱

,型別,作用域,生存期等等),對應的只是一塊記憶體(只有首址和大小), 所以在

執行期間動態申請的空間,是需要額外的程式碼維護,以確保不同變數不會混用記憶體。比

如寫new表示有一塊記憶體已經被佔用了,其它變數就不能再用它了; 寫delete表示這塊

記憶體自由了,可以被其它變數使用了。(通常我們都是通過變數來使用記憶體的,就編碼

而言變數是給記憶體塊起了個名字,用以區分彼此)


記憶體申請和釋放時機很重要,過早會丟失資料,過遲會耗費記憶體。特定情況下編譯器可

以幫我們完成這項複雜的工作(增加額外的程式碼維護記憶體空間,實現申請和釋 放)。

從這個意義上講,區域性自動變數也是由編譯器負責分配空間的。進一步講,記憶體管理用

到了我們常常掛在嘴邊的堆和棧這兩種資料結構。


最後對於“編譯器分配空間”這種不嚴謹的說法,你可以理解成編譯期間它為你規劃好

了這些變數的記憶體使用方案,這個方案寫到可執行檔案裡面了(該檔案中包含若干並非

出自你大腦衍生的程式碼),直到程式執行時才真正拿出來執行!

 

關於這點我的理解:


書上的確可以看到,關於編譯時就分配記憶體的概念,比如:“當一個數組被宣告時,它

所需要的記憶體在編譯時就被分配了。”

當我看到這時也很迷惑,認真思考後認為,它的意思是變數的記憶體大小被分配了,記憶體

地址當然是不知道的。我們把這種分配方式叫靜態分配。

全域性和靜態資料在編譯時就靜態分配了,但它們在載入到記憶體之前是不佔“太多磁碟空

間”,它在磁碟上以ELF或其它格式儲存時,只有一些描述資訊,並不是你聲明瞭一個

很大的陣列就會佔很大的磁碟空間,它們在載入到記憶體後才變大的。載入器按靜態分配

時的大小,為它在記憶體中分配固定的空間。


所以全域性資料,無論是初始化的,還是未初始化的,在記憶體中都是佔它實際大小的記憶體

的。但在ELF格式時,只佔一些描述符所需大小的磁碟空間。


C,C++記憶體模型從上到下一次是棧區,堆區,全域性區,常量區,程式碼區