c shared ptr使用的幾點注意

2021-09-09 05:45:49 字數 3102 閱讀 6593

先介紹一下shared_ptr.是c++為了提高指標安全性而新增的智慧型指標,方便了記憶體管理。功能非常強大,非常強大,非常強大(不單單是shared_ptr,配合week_ptr以及enable_share_from_this()以及share_from_this())!!!對於支援智慧型指標的c++版本程式設計,能用智慧型指標就用智慧型指標!

shared_ptr是一種智慧型指標(smart pointer),作用有如同指標,但會記錄有多少個shared_ptrs共同指向乙個物件。這便是所謂的引用計數(reference counting)。一旦最後乙個這樣的指標被銷毀,也就是一旦某個物件的引用計數變為0,這個物件會被自動刪除。這在非環形資料結構中防止資源洩露很有幫助。使得指標可以共享物件,並且不用考慮記憶體洩漏問題

shared_ptr 可以支援普通指標的所有操作,完全可以像操作普通指標一樣操作智慧型指標。

shared_ptr 可以通過三種方式得到(拷貝初始化,定義delete操作的方式不在羅列,只討論初始化指標所指物件**):

1.通過乙個指向堆上申請的空間的指標初始化(切記不要用棧上的指標,否則,當智慧型指標全部釋放控制權(棧中的物件離開作用域本身就會析構一次),將會析構物件,導致出錯)

2.通過make_shared函式得到

3.通過另外乙個智慧型指標初始化

下面是使用shared_ptr 的一些注意事項:

1. shared_ptr多次引用同一資料,會導致兩次釋放同一記憶體。如下:

2.使用shared_ptr包裝this指標帶來的問題,如下:(

換句話來說,就是使用智慧型指標控制棧變數的問題

)

class tester 

public:

shared_ptrsget()

};int main()

也將導致兩次釋放t物件破壞堆疊,一次是出棧時析構,一次就是shared_ptr析構。若有這種需要,可以使用下面**。

class tester : public enable_shared_from_this

public:

shared_ptrsget()

};int main()

3. shared_ptr迴圈引用導致記憶體洩露,**如下:

class parent;

class child; 

typedef shared_ptrparent_ptr;

typedef shared_ptrchild_ptr; 

int main()

class parent

public:

child_ptr children;

};class child

public:

parent_ptr parent;

};

如上**,將在程式退出前,father的引用計數為2,son的計數也為2,退出時,shared_ptr所作操作就是簡單的將計數減1,如果為0則釋放,顯然,這個情況下,引用計數不為0,於是造成father和son所指向的記憶體得不到釋放,導致記憶體洩露

4.在多執行緒程式中使用shared_ptr應注意的問題。**如下:

class tester 

~tester() {}

// 更多的函式定義…

};void fun(shared_ptrsp)

int main()

這個**帶來的問題很顯然,由於多執行緒同時訪問智慧型指標,並將其賦值到其它同類智慧型指標時,很可能發生兩個執行緒同時在操作引用計數(但並不一定絕對發生),而導致計數失敗或無效等情況,從而導致程式崩潰,如若不知根源,就無法查詢這個bug,那就只能向上帝祈禱程式能正常執行。

引入weak_ptr可以解決這個問題,將fun函式修改如下:

void fun(weak_ptrwp)

else

} 5.weak_ptr不僅可以解決多執行緒訪問帶來的安全問題,而且還可以解決上面第三個問題迴圈引用。children類**修改如下,即可打破迴圈引用:

class child

public:

weak_ptrparent;

};因為weak_ptr不增加引用計數,所以可以在退出函式域時,正確的析構。

weak_ptr 介紹:

weak_ptr是為了配合shared_ptr而引入的一種智慧型指標,它更像是shared_ptr的乙個助手而不是智慧型指標,因為它不具有普通指標的行為,沒有過載operator*和->,它的最大作用在於協助shared_ptr工作,像旁觀者那樣觀測資源的使用情況.

用法:weak_ptr被設計為與shared_ptr共同工作,可以從乙個shared_ptr或者另乙個weak_ptr物件構造,獲得資源的觀測權。但weak_ptr沒有共享資源,它的構造不會引起指標引用計數的增加。

使用weak_ptr的成員函式use_count()可以觀測資源的引用計數,另乙個成員函式expired()的功能等價於use_count()==0,但更快,表示被觀測的資源(也就是shared_ptr的管理的資源)已經不復存在。

weak_ptr可以使用乙個非常重要的成員函式lock()從被觀測的shared_ptr獲得乙個可用的shared_ptr物件, 從而操作資源。但當expired()==true的時候,lock()函式將返回乙個儲存空指標的shared_ptr.

share_ptr 的 aliasing constructor:

可以使得share_ptr 擁有某個物件控制權的時候,儲存指標(storage pointer,shared_ptr 還有乙個概念叫owned ptr 指向儲存當前控制物件相關資訊)指向另外乙個物件,模板如下:

template shared_ptr (const shared_ptr& x, element_type* p) noexcept;

該建構函式是的shared_ptr 管理 x 指標指向物件,會將計數器加一,並且在釋放控制權時減一,如有需要還會呼叫析構函式,但是不同的是它storage ptr 指向的是p,呼叫 share_ptr.get() 會返回 p ,一般的用途在 p所指物件是x所指物件的成員或者別名(alias)[這段是翻譯的,總之,aliasing constructor 還是慎用吧]

原文: 

C shared ptr使用時的幾個問題

shared ptr.是c 為了提高指標安全性而新增的智慧型指標,方便了記憶體管理。功能強大,但是也要注意以下問題 int pintvalue newint shared ptr int shptr pintvalue 語法錯誤 shptr pintvalue 語法錯誤int pintarr new...

C shared ptr的模擬實現

一 shared ptr的模擬實現 我在之前的部落格 智慧型指標 中有說過shared ptr的原理,那麼這篇部落格,我們模擬實現乙個shared ptr,讓大家能更好的理解它的原理。include 這個標頭檔案是用來使用互斥鎖 templateclass shared ptr 該函式是為了對引用計...

c shared ptr智慧型指標使用注意事項

shared ptr在boost中地位相當重要,其行為最接近原始指標,但又比指標更加安全,甚至還能提供基本的執行緒安全保證。它基本上解決了在使用c 開發過程中不可避免的使用指標而遇到的許多問題,常見的毫無疑問是記憶體洩漏和記憶體的提前釋放,還有一些關於指標記憶體申請而產生的異常問題等。而要想較好的使...