全域性物件在程式啟動時分配,在程式結束時銷毀。
區域性自動物件,當我們進入其定義所在的程式塊時被建立,在離開塊時銷毀。
區域性 static 物件在第一次使用前分配,在程式結束時銷毀
靜態記憶體用來儲存區域性static物件,類static 資料成員,以及定義在任何函式之外的變數。
棧記憶體用來儲存定義在函式內的非static物件。分配在靜態或棧記憶體中的物件由編譯器自動建立和銷毀。
對於棧物件,僅在其定義的程式塊執行時才存在,static物件在使用之前分配,在程式銷毀時結束。
除了靜態記憶體和棧記憶體,每個程式還擁有乙個記憶體池。這部分記憶體被稱為自由空間或堆(heap)。程式用堆來儲存動態分配的物件。動態物件不在使用的時候,**必須顯式的銷毀它們。
在自由空間分配的記憶體是無名的,因此 new 無法為其分配物件命名,而是返回乙個指向該物件的指標
//p 指向乙個動態分配的、未初始化的無名物件
int *p = new
int;
預設情況下,動態分配的物件是預設初始化的,這意味著內建型別或組合型別的物件的值將是未定義的,而類型別物件將用預設建構函式進行初始化
//初始化為空string
string *ps = new
string;
//pi指向乙個未初始化的int
int *pi = new
int;
我們可以用直接初始化方式來初始化乙個動態分配的物件。可以使用傳統的構造方式,在c++11中,也可以使用列表初始化
// p 指向的物件的值為1024
int *p = new
int(1024);
//ps指向的物件的為『9999999999』
string *ps = new
string(10, '9');
//pv五個元素,值為 0 1 2 3 4
vector
*pv = new
vector
;
也可以對動態分配的物件進行值初始化,只需在型別名之後跟一對空括號即可。
string *ps1 = new
string; // 預設初始化為空string
string *ps2 = new
string() // 值初始化為空string
int *pi1 = new
int; // 預設初始化 *pi1值未定義
int *pi2 = new
int(); //值初始化為0;*pi2為0
對於定義了自己的建構函式的類型別(例如string)來說,要求值初始化是沒有意義的。不管採用什麼形式,物件都會通過預設建構函式來初始化,但對於內建型別,兩種形式的差別就很大了;值初始化的內建型別有著良好定義的值,而預設初始化的物件的值則是未定的。類似的,對於類中那些依賴於編譯器合成的預設建構函式的內建型別成員,那麼它們的值也是未定義的。
如果我們提供了乙個括號包圍的初始化器,就可以使用auto。從此初始化器來推斷我們想要分配的物件的型別。但是,由於編譯器要用初始化的型別來推斷要分配的型別,只有當括號中僅有單一初始化器時才可以使用auto
auto p1 = new
auto(obj); // p指向乙個與obj型別相同的物件
//該物件用obj進行初始化
auto p2 = new
auto(a, b, c); //錯誤 括號中只能有單個初始化器
用new分配const物件是合法的
//分配並初始化乙個const int
const
int *pci = new
const
int(1024);
//分配並預設初始化乙個const的空string
const
string *pcs = new
const
string;
類似於其他任何const物件,乙個動態分配的const物件必須進行初始化,對於乙個定義了預設建構函式的類型別,其const 動態物件可以隱式初始化,而其他型別的物件就必須顯式初始化。由於分配的物件是const的,new返回的指標是乙個指向const的指標
一旦乙個程式用光了它所有可用的記憶體,new表示式就會失敗,預設情況下,如果new不能分配所要求的空間記憶體,它會丟擲乙個型別為 bad_alloc 的異常。我們可以改變使用new的方式來阻止它丟擲異常
// 如果分配失敗,new返回乙個空指標
int *p = new
int;
int *p1 = new (nothrow) int; //如果分配失敗,new返回乙個空指標
我們稱這種形式的new為定位new
為了防止記憶體耗盡,在動態記憶體使用完畢之後,必須將其歸還給系統,我們用delete 來將動態記憶體歸還給系統。
與new類似,delete表示式也執行兩個動作,銷毀給定的指標指向的物件,釋放對應得記憶體。
C 動態記憶體
了解動態記憶體在 c 中是如何工作的是成為一名合格的 c 程式設計師必不可少的。c 程式中的記憶體分為兩個部分 很多時候,您無法提前預知需要多少記憶體來儲存某個定義變數中的特定資訊,所需記憶體的大小需要在執行時才能確定。在 c 中,您可以使用特殊的運算子為給定型別的變數在執行時分配堆內的記憶體,這會...
C 動態記憶體
棧 在函式內部宣告的所有變數都將占用棧記憶體 堆 這是程式中未使用的記憶體,在程式執行時可用於動態分配記憶體 new和delet運算子 動態分配記憶體的通用語法 new data type 如果自由儲存區已被用完,可能無法成功分配記憶體。所以建議檢查 new 運算子是否返回 null 指標,並採取以...
C 動態記憶體
到目前為止,我們的程式中我們只用了宣告變數 陣列和其他物件 objects 所必需的記憶體空間,這些記憶體空間的大小都在程式執行之前就已經確定了。但如果我們需要記憶體大小為乙個變數,其數值只有在程式執行時 runtime 才能確定,例如有些情況下我們需要根據使用者輸入來決定必需的記憶體空間,那麼我們...