auto ptr 與 delete 的區別

2021-05-01 02:18:05 字數 2328 閱讀 7427

template

class auto_ptr ;

這是auto_ptr類,可知auto_ptr建立的是乙個類物件,當這個物件消失時,會自動呼叫析構函式~auto_ptr();

讓我們來看看~auto_ptr();函式的實現:

~auto_ptr()

這裡呼叫了delete。

所以它們的不同就是:auto_ptr建立的是乙個物件,而new與delete只是函式!使用auto_ptr就不會因為忘了delete掉而出現記憶體溢位了。

下面是一篇好文章值得一看:

動態記憶體使用最多的是在c++應用程式的**中。有過程式設計經驗的程式設計師雖然都知道new操作符的使用一定要與delete匹配,在某些場合仍然可能有記憶體溢位。當異常被擲出時,程式的正常控制流程被改變,因此導致潛在的記憶體溢位。例如, 

void g() //可能擲出

void func()

int main()

catch(...){}}

當 g 擲出乙個異常,異常處理機制展開堆疊:g()退出,同時控制被轉移到 main() 的 catch(...)**塊。這時,無論怎樣,func()中的delete語句都不會被執行,由此導致pstr的記憶體溢位。要是使用區域性自動串變數,而不是使用動態分配-記憶體溢位就不會出現了:

string str; //區域性自動物件

g(); //沒有記憶體溢位 

許多資料重要的結構以及應用,象鍊錶,stl容器,串,資料庫系統以及互動式應用必須使用動態記憶體分配,因此仍然冒著萬一發生異常導致記憶體溢位的風險。c++標準化委員會意識到了這個漏洞並在標準庫中新增了乙個特殊的類模板,它就是std::auto_ptr,其目的是促使動態記憶體和異常之前進行平滑的互動。auto_ptr保證當異常擲出時分配的物件(即:new操作符分配的物件)能被自動銷毀,記憶體能被自動釋放。下面我們就來討論使用動態記憶體時,如何正確和有效地使用auto_ptr來避免資源溢位。這個技術適用於檔案,執行緒,鎖定以及與此類似的資源。

auto_ptr的定義可以在中找到。與標準庫中其它的成員一樣,它被宣告在命名空間std::中。當你例項化auto_ptr物件時,對它進行初始化的方法是用乙個指標指向動態分配的物件,下面是例項化和初始化auto_ptr物件的例子: 

include

#include

using namespace std;

void func()

auto_ptr後面的尖括弧裡指定auto_ptr指標的型別,在這個例子中是string。然後auto_ptr控制代碼的名字,在這個例子中是pstr。最後是用動態分配的物件指標初始化這個例項。注意你只能使用auto_ptr構造器的拷貝,也就是說,下面的**是非法的: 

auto_ptrpstr  = new string; //編譯出錯

auto_ptr是乙個模板,因此它是完全通用的。它可以指向任何型別的物件,包括基本的資料型別: 

auto_ptrpi  (new int);

一旦你例項化乙個auto_ptr,並用動態分配的物件位址對它進行了初始化,就可以將它當作普通的物件指標使用,例如: 

*pstr = "hello world"; //賦值

pstr->size(); //呼叫成員函式

之所以能這樣做是因為auto_ptr過載了操作符&,*和->。不要被語法誤導,記住pstr是乙個物件,不是乙個指標。

auto_ptr是如何解決前面提到的記憶體溢位問題呢?auto_ptr的析構函式自動摧毀它繫結的動態分配物件。換句話說,當pstr的析構函式執行時,它刪除構造pstr期間建立的串指標。你絕不能刪除auto_ptr,因為它是乙個本地物件,它的析構函式是被自動呼叫的。讓我們看一下函式func()的修訂版本,這次使用了auto_ptr: 

void func()

c++保證在堆疊展開過程中,自動儲存型別的物件被自動摧毀。因此,如果g()擲出異常,pstr的析構函式將會在控制被轉移到catch(...)塊之前執行。因為pstr的析構函式刪除其繫結的串指標,所以不會有記憶體溢位發生。這樣我們在使用動態分配物件時,利用auto_ptr就實現了自動和安全的本地物件。

如何避免使用auto_ptr的缺陷

auto_ptr並不是完美無缺的,它的確很方便,但也有缺陷,在使用時要注意避免。首先,不要將auto_ptr物件作為stl容器的元素。c++標準明確禁止這樣做,否則可能會碰到不可預見的結果。

auto_ptr的另乙個缺陷是將陣列作為auto_ptr的引數: 

auto_ptrpstr (new char[12] ); //陣列;為定義

記住不管什麼時候使用陣列的new操作時,必須要用delete來摧毀陣列。因為auto_ptr的析構函式只對非陣列型別起作用。所以陣列是不能被正確摧毀的話,程式的行為是不明確的。總之,auto_ptr控制乙個由new分配的單物件指標,僅此而已。

delete與delete 的區別

c 告訴我們在 用 new 分配的單個物件的記憶體空間的時候用 delete,用 new 分配的一組物件的記憶體空間的時候用 delete。很多人注意到了這個問題,但是卻不清楚為什麼要這樣做,不這樣做行不行。關於 new 和 delete,其中又分為兩種情況 1 為基本資料型別分配和 空間 2 為自...

delete與delete 的區別

如果是基本型別陣列呼叫delete就可以刪除之,而乙個自定義的結構陣列,卻最好使用delete,為什麼?原因如下 y new 10 delete y 10個元素所佔的記憶體都會被釋放,但是 如果有析構函式的話,只有第乙個元素的析構函式被呼叫,其他9個元素的析構函式沒有被呼叫 如果 的析構函式裡面有記...

delete與delete 的區別

一直很好奇delete 和 delete 有什麼不同?今天我從彙編的角度看一看 測試源 include int main 使用vs2019檢視其內部實現 可以看到兩個內部實現是一樣的,說明delete 和 delete 使用沒有區別 可是在網上查詢資料說,當析構物件陣列時必須要用delete 如果使...