C 異常 與智慧型指標

2021-06-26 15:24:53 字數 1746 閱讀 3708

void func1 ( )

上面是個很露骨的」異常不安全「的例子。

一旦發生異常,p申請的記憶體將得不到釋放。

乙個簡單的辦法是:

int * p = new int(1024);

trycatch(...)

delete p;

還有種方法是定義乙個簡單的類ptr,它含有乙個指標成員。該類的析構函式會釋放這個指標所指物件的記憶體。

void func1 ( )

因為不論有沒有異常發生,都要退func1的棧,p是在棧上的物件,退棧時自動呼叫了它的析構函式,從而釋放了int的記憶體。

不論有沒有異常發生,都要退棧;可以把這點看做類似c#的finally子句,來利用。

不過上面ptr類只是乙個示範,too *****,具體請參照c++ prmer的第13章 複製控制 管理指標成員,講述了引用計數,和std、boost中的智慧型指標,會用就可以了。

不只是釋放記憶體,對於其它的資源也是一樣的,比如加鎖與釋放鎖。

void func ( void * area)

應該改為:

void func ( void * area)

// lk.locker::~locker();

在建構函式中分配資源,在析構函式中釋放。即所謂的raii:

resource acquisition is initialization 

資源獲取即初始化

奇怪的是c++ primer書上雖然講了引用計數,卻只介紹了不使用計數的std::auto_ptr?

std::auto_ptr的設計使它具有以下四條行為邏輯(四條限制):

1)std::auto_ptr只能儲存指向動態分配物件的指標。因為std::auto_ptr本身被撤銷的時候會動態釋放它儲存的指標所指向的記憶體,所以得是動態分配的。

2)不要讓兩個std::auto_ptr指向同乙個物件,否則將來這兩個std::auto_ptr被撤銷的時候,那個物件被釋放兩次!

3)std::auto_ptr不能儲存指向動態分配的陣列的指標。因為std::auto_ptr中使用的是delete,而不是delete。

4)std::auto_ptr之間的複製和賦值被定義成了「轉移式」,被轉移的那個std::auto_ptr變成未繫結的。複製和賦值之後兩個物件不相等,因此,不能將std::auto_ptr儲存在標準庫容器中。

但std::auto_ptr自c++11起,被標記為deprecated,不贊成使用的,而是用它的替代unique_ptr。

相關歷史請看這兒:

2023年. greg colvin向c++標準委員會提出了自己設計的智慧型指標:auto_ptr和counted_ptr。auto_ptr實現基本的raii管理,不可複製;counted_ptr採用引用計數實現了乙個可複製的智慧型指標。兩者用於不同的場合。  但是標準委員會最終只通過了auto_ptr,並且對auto_ptr加入了乙個古怪的「所有權轉移」語義。後來auto_ptr和counted_ptr進入了boost c++ 庫,改名為scoped_ptr和shared_ptr。

std的auto_ptr與unique_ptr之間的區別:簡言之,後者可以支援陣列、可以放入容器、不支援拷貝(而是使用move語義)

這裡是std中的智慧型指標: 

also so see the 

智慧型指標和異常

使用異常處理的程式能在異常發生後令程式流程繼續,同時要注意的是,這種程式需要確保在異常發生後資源能被正確地釋放。乙個簡單的確保資源被釋放的方法是使用智慧型指標。如果使用智慧型指標,即使程式塊過早結束,智慧型指標類也能確保在記憶體不再需要時將其釋放 void func 在函式結束時shared ptr...

智慧型指標和異常

今天讓我們來分析一下c 中的智慧型指標和異常,首先呢先普及一下概念!1 智慧型指標 智慧型或者自動化的管理指標所會向的動態資源的釋放。2 異常 當乙個函式發現自己無法處理的錯誤時,讓函式的呼叫者直接或間接的處理這個問題。3 raii 資源分配即初始化。建構函式完成物件的初始化,析構函式完成物件的清理...

C 智慧型指標與容器

1,智慧型指標預設刪除了複製建構函式,所以在使用智慧型指標過程中一旦無意中用到了其複製建構函式,便會出現c2280的錯誤,顯示引用已經刪除的函式。2,標準容器中存放的元素為智慧型指標時,應該返回為這個容器的引用,且最好是常引用,若是直接返回整個容器,便會呼叫複製建構函式 當vector使用resiz...