c++定義了兩個運算子來分配和釋放動態記憶體。new分配記憶體,delete釋放new分配的記憶體。
相對於智慧型指標,使用這個兩個運算子非常容易出錯。因為它不能依賴類物件拷貝、賦值和銷毀操作的任何預設定義。
預設情況下,動態分配的物件是預設初始化的。這意味著內建型別或組合型別的值將是未定義的。而類型別的物件將用預設的建構函式進行初始化。
string *ps = new
string;//ps指向乙個動態分配的,初始化為空的string
int *pi = new
int;//pi指向乙個未初始化的int
也可以使用直接初始化方式或者傳統構造方式來初始化乙個動態分配的物件。
string *pt = new
string("d");//pt指向乙個初始化為d的string
int *pd = new
int(2048);//pd指向的物件的值為2048
或者對動態分配的物件進行值初始化,只需要在型別名後面跟乙個空括號即可。
string *sp = new
string();//值初始化為空string
int *dp = new
int();//值初始化為0 *dp為0
一旦乙個程式用光了它所有的可用的記憶體,new表示式就會失敗。如果new不能分配所要求的記憶體空間,他會丟擲乙個型別為bad_alloc的異常。我們可以改變使用new的方式來阻止它丟擲的異常。
//如果分配失敗,new丟擲std::bad_alloc異常
int *p1 = new
int;
//如果分配時候,new返回乙個空指標。
int *p2 = new (nothrow) int;
我們通常使用delete表示式來將動態記憶體歸還給系統。delete表示式接收乙個指標,指向我們想要釋放的物件。
int i, *pi1 = &i, *pi2 = nullptr;
double *pd = new
double(33), *pd2 = pd;
delete i;//錯誤,i不是乙個指標
delete pi1;//未定義,pi1指向乙個區域性變數
delete pd;//正確
delete pd2;//未定義,pd2指向的記憶體已經被釋放了
delete pi2;//正確,釋放乙個空指標總是沒有錯誤的
返回指向動態記憶體的指標(不是智慧型指標)的函式給其呼叫者增加了乙個額外的負擔—呼叫者必須記得釋放記憶體。
(忘記釋放記憶體的例子)
foo* factory(t arg)
void use_factory(t arg)//p離開了他的作用域,但它指向的記憶體沒有釋放!
正確的做法:
void use_factory(t arg)
或者還有一種可能,我們系統中的其他**要使用use_factory函式所分配的物件,我們就應該修改此函式,讓他返回乙個指標,指向它分配的記憶體。
void use_factory(t arg)
當我們delete乙個指標後,指標值就變得無效了。但是在很多機器上指標仍然儲存著(已經釋放了的)動態記憶體的位址。在delete之後,指標就變成了人們所說的空懸指標。
如何避免空懸指標呢?在指標即將要離開其作用域之前釋放掉它所關聯的記憶體。這樣,在指標關聯的記憶體被釋放掉之後,就沒有機會繼續使用指標了。如果我們需要保留指標,可以在delete之後將nullptr賦予指標,這樣就清楚的指出指標不指向任何物件。
int *p(new
int(42));//p指向動態記憶體
auto q = p;//p和q指向相同的記憶體
delete p;//p和q均變無敵
p = nullptr;//指出p不再繫結到任何物件
但是,重置p對q沒有任何作用,在我們釋放p所指向的(同時也是q所指向的!)記憶體時,q也變得無效了。 記憶體管理 智慧型指標之shared array
shared array類似shared ptr,它包裝了new操作符在堆上分配的動態陣列,同樣使用引用計數機制為動態陣列提供了乙個 可以在程式的生命同期裡長期存在,直到沒有任何引用後才釋放記憶體。類摘要 templateclass shared array shared array與shared ...
C 之智慧型指標
本文發表於1999年10月份的c c users journal,17 10 1.為什麼稱它為 自動 指標?auto ptr只是眾多可能的智慧型指標之一。許多商業庫提供了更複雜的智慧型指標,用途廣泛而令人驚異,從管理引用的數量到提供先進的 服務。可以把標準c auto ptr看作智慧型指標的ford...
C 之智慧型指標
c 中有四個智慧型指標 auto ptr,shared ptr,weak ptr,unique ptr,其中後三個是c 11支援,並且第乙個已經被c 11棄用。智慧型指標從書面意思來說,就是智慧型。主要是動態記憶體的使用很容易出問題,要在正確的時間正確釋放記憶體是很困難的。有時我們可能忘了釋放記憶體...