談談智慧型指標

2021-07-11 14:46:59 字數 2228 閱讀 9709

使用new和delete來管理動態記憶體常出的一些錯誤:

1.忘記delete,即導致了「記憶體洩漏」,

2.野指標。在物件已經被釋放掉之後,(這裡注意,此時的指標成為了懸垂指標,即指向曾經存在的物件,但該物件已經不再存在。結果未定義,而且難以檢測。)這時候我們再次使用,會產生使用非法記憶體的指標。

不過如果我們需要保留指標,可以在delete以後將nullptr賦予指標,這樣指標就不指向任何物件了,如下**:

auto p(new auto 42);

auto q = p;

delete p;

p = nullptr;

題外話:在測試這個問題的時候,我輸出了下q的值發現還是42,並且沒有報錯,後來在delete p之後,我又給*p = 19;這個時候 p ,q的值在輸出的時候都是19,也沒有報錯。這個**其實根本就是錯誤的了,因為p,q已經沒有有效的記憶體空間了。這裡是釋放了記憶體,但指標的值不變,指向的記憶體不會清0,指向的這片記憶體區域是待分配的,如果沒有被其他資料覆蓋的話,你就能幸運得輸出這主要原因是你分配的記憶體小,沒有繼續分配,被占用的概率小所致。我用的xcode,換到vs下就正常報錯了,是因為vs為了從編譯器的角度上解決緩衝區溢位等問題,加上的這種功能,c++標準裡面沒有這麼要求,所有xcode和gcc是不會檢查的。所以在這裡 建議大家寫純c++**的時候用vs。

3.重複delete,就會使自由空間遭到破壞

智慧型指標和普通指標的區別在於智慧型指標實際上是對普通指標加了一層封裝機制,這樣的一層封裝機制的目的是為了使得智慧型指標可以方便的管理乙個物件的生命期。

在c++中,我們知道,如果使用普通指標來建立乙個指向某個物件的指標,那麼在使用完這個物件之後我們需要自己刪除它,例如:

objecttype* temp_ptr = new objecttype();

temp_ptr->foo();

delete temp_ptr;

很多材料上都會指出說如果程式設計師忘記在呼叫完temp_ptr之後刪除temp_ptr,那麼會造成乙個懸掛指標(dangling pointer),也就是說這個指標現在指向的記憶體區域其內容程式設計師無法把握和控制,也可能非常容易造成記憶體洩漏。

可是事實上,不止是「忘記」,在上述的這一段程式中,如果foo()在執行時丟擲異常,那麼temp_ptr所指向的物件仍然不會被安全刪除。

在這個時候,智慧型指標的出現實際上就是為了可以方便的控制物件的生命期,在智慧型指標中,乙個物件什麼時候和在什麼條件下要被析構或者是刪除是受智慧型指標本身決定的,使用者並不需要管理。

所以就出現了智慧型指標這種東西:

智慧型指標

(英語:smart pointer

)是一種抽象的

資料型別

。在程式設計中,它通常是經由類模板(class template)來實做,藉由模板(template)來達成泛型,通常藉由類(class)的析構函式來達成自動釋放指標所指向的記憶體或物件。(維基百科)

c++  有三種智慧型指標auto_ptr、unique_ptr 和shared_ptr,以及weak_ptr.

c++11中提供了std::unique_ptr,定義在標頭檔案中。

c++11新增了move語義,相比copy語義,它能更好的實現值傳遞.std::auto_ptr使用的是copy語義,為了向前相容,c++11沒有修改std::auto_ptr,而是引入了新的使用move語義的std::unique_ptr.

uniqu_ptr的拷貝建構函式和賦值運算子都宣告為deleted,也就是說它不能被拷貝,只能通過std::move來轉遞它所指向的記憶體的所有權。

也就是如果是右值的話就可以給其他物件賦值,其他存在時間長的物件都不可以進行拷貝,只能使用c11 move語義實現記憶體所有權的傳遞

另外對於shared_ptr和weak_ptr

std::shared_ptr使用引用計數,所以有

迴圈計數

的問題。為了打破迴圈,可以使用std::weak_ptr.顧名思義, weak_ptr是乙個弱引用,只引用,不計數。如果一塊記憶體被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該記憶體,記憶體也會被釋放。所以weak_ptr不保證它指向的記憶體一定是有效的,在使用之前需要檢查。

參考:2: 維基百科:

智慧型指標 強弱智慧型指標

在平時編寫 的時候經常會用到new來開闢空間,而我們開闢出來的空間必須得手動去delete他,但是如果程式設計師忘記去手動釋放那邊會出現乙個麻煩的問題,記憶體洩漏!或者是一塊記憶體被多個函式同時使用時,如果其中乙個函式不知道還有其他人也在使用這塊記憶體而釋放掉的話同樣也會引起程式的崩潰。引起記憶體洩...

智慧型指標學習

最近接觸到智慧型指標很多,於是研究了一下智慧型指標的原理,寫下自己的心得體會,有不對的還請指正。智慧型指標產生的目的 因為在c 中,存在非常複雜的指標錯誤問題,例如,某個物件生成後,指向該物件的指標可能有多個,當我們用delete語句刪除其中的乙個指標後,物件就被銷毀,那麼其餘指向該物件的指標就會懸...

智慧型指標3

include include using namespace std define test smartptr class stub class sentry sentry private int lock template class refcountingtraits void unrefer...