在c++中,直接對動態記憶體的管理是通過運算子new和delete來完成的。
一、使用new動態分配和初始化物件的幾種方式:
1. 預設情況下,動態分配的物件是預設初始化的,故內建型別或組合型別的物件的值是未定義的,類型別物件將用預設建構函式進行初始化
int *pi = new
int; //pi指向乙個動態分配的,未初始化的無名物件
string *ps = new
string; //初始化為空string
2. 使用直接初始化方式來初始化乙個動態物件,可以使用傳統的構造方式(使用括號),在新標準下,也可以使用列表初始化(使用花括號)
int *pi = new
int(1024);
string *ps = new
string(10, '9');
vector
*pv = new
vector
;
3. 對動態物件進行值初始化,在型別名之後跟一對空括號,主要針對內建型別,對於類型別,不管是預設初始化或值初始化都是通過預設建構函式來初始化的
string *ps = new
string; //預設初始化為空string
string *ps = new
string(); //值初始化為空string
int *pi1 = new
int; //預設初始化,*pi1值未定義
int *pi2 = new
int(); //值初始化為0,*pi2為0;
4. 使用乙個括號包圍的單一初始化器,編譯器用初始化器的型別推斷要分配的型別
auto p1 = new
auto(obj); //p指向乙個與obj型別相同的物件
auto p2 = new
auto; //錯誤的
5. 動態分配const物件
const
int *pci = new
const
int(1024); //const物件必須要初始化
二、delete指標:
傳遞給delete的指標必須指向動態分配的記憶體或是乙個空指標,釋放一塊並非new分配的記憶體,或者將相同的指標釋放多次,其行為是未定義的。
使用new和delete管理記憶體存在的常見問題:
三、智慧型指標
為了更容易(同時也安全)地使用動態記憶體,新的標準庫提供了兩種智慧型指標型別來管理動態物件。智慧型指標的行為類似常規指標,重要的區別是它負責自動釋放所指向的物件。新標準庫提供的這兩種智慧型指標的區別在於管理底層指標的方式:shared_ptr允許多個指標指向同一物件;unique_ptr則「獨佔」所指向的物件。標準庫還定義了乙個名為weak_ptr的伴隨類,它是一種弱引用,指向shared_ptr所管理的物件。
智慧型指標也是模板,當建立乙個智慧型指標時,必須提供額外的資訊-指標可以指向的型別。
最安全的分配和使用動態記憶體的方法是呼叫make_shared函式,此函式在動態記憶體中分配乙個物件並初始化它,返回指向此物件的shared_ptr
shared_ptr
p3 = make_shared(42);
每乙個shared_ptr都有乙個關聯的計數器,稱為引用計數,用來記錄有多少乙個其他的share_ptr指向相同的物件,當指向乙個物件的最後乙個shared_ptr被銷毀時,share_ptr類會通過另乙個特殊的成員函式-析構函式自動銷毀此物件。
四、allocator類
new缺乏一些靈活性,因為它組合了記憶體分配和物件構造,當分配一大塊記憶體時,如果希望在這塊記憶體上按需構造物件,即將記憶體分配和物件構造分離。allocator類提供了一種型別感知的記憶體分配方法,它分配的記憶體是原始的,未構造的。
allocator是乙個模板,它根據給定的物件型別來確定恰當的記憶體大小和對齊位置
allocator alloc; //可分配string的aallocator物件
auto
const p = alloc.allocate(n); //分配n個未初始化的string
allocator類還有兩個伴隨演算法,可以在未初始化記憶體中建立物件:
注意:只能對構造了的元素進行destroy操作,元素被銷毀後可以重新使用這部分記憶體,釋放記憶體通過呼叫deallocate。
五、程式使用動態記憶體處於以下三種原因之一:
容器類是處於第一種原因而使用動態記憶體的典型例子。
使用動態記憶體的乙個常見原因是執行多個物件共享相同的狀態。
C 動態記憶體
了解動態記憶體在 c 中是如何工作的是成為一名合格的 c 程式設計師必不可少的。c 程式中的記憶體分為兩個部分 很多時候,您無法提前預知需要多少記憶體來儲存某個定義變數中的特定資訊,所需記憶體的大小需要在執行時才能確定。在 c 中,您可以使用特殊的運算子為給定型別的變數在執行時分配堆內的記憶體,這會...
C 動態記憶體
棧 在函式內部宣告的所有變數都將占用棧記憶體 堆 這是程式中未使用的記憶體,在程式執行時可用於動態分配記憶體 new和delet運算子 動態分配記憶體的通用語法 new data type 如果自由儲存區已被用完,可能無法成功分配記憶體。所以建議檢查 new 運算子是否返回 null 指標,並採取以...
C 動態記憶體
到目前為止,我們的程式中我們只用了宣告變數 陣列和其他物件 objects 所必需的記憶體空間,這些記憶體空間的大小都在程式執行之前就已經確定了。但如果我們需要記憶體大小為乙個變數,其數值只有在程式執行時 runtime 才能確定,例如有些情況下我們需要根據使用者輸入來決定必需的記憶體空間,那麼我們...