參考自https://www.cnblogs.com/round1/p/12906648.html
主要為了避免以下Bug:
內存泄露? ?:對象無法被釋放,最常見的問題。
野指針? ? ? ?: 指針指向未知。
重復釋放? ?:? ? 顧名思義。
?
?
(一)內存泄露 :?
?1. 拋出異常,函數中途退出,釋放操作沒有執行
C * c = new C; throw; //拋出 delete c; //沒有執行
2 . 忘記釋放
注意:? 指針變量(值語義)一旦被銷毀,所指向的對象(對象語義)將無法釋放
void f() {C * c = new C();
//delete c; //忽略 }
?
結果:內存無法釋放,直到壓榨完程序的所以內存。
?
(二)野指針 :
1. 未初始化
C * c;//指向哪呢???
2.? 指針變量指向的對象被釋放后,指針就變成了野指針,注意:即使釋放完馬上置空,仍然非常容易出錯。
C * c = new C();
C * c2 = c;
delete c;
c = nullptr; //釋放并置空
//c2 = nullptr
c2非常容易被忽略。你永遠不知道有多少個c2, c3,在什么地方存在這些指針。
?
結果:未定義,不可預測的行為
?
(三)重復釋放 :
c2 = c;
delete c; delete c2;
??
結果:程序異常結束。
?
?
智能指針
上一章提到,值語義對象作為局部變量,存儲在棧區,生命周期由程序管理,因此值語義可以作為資源句柄。
這個技術叫做RALL,在資源句柄的構造函數進行資源初始化,在析構函數進行資源釋放。
智能指針,就是值語義的資源句柄。將對象語義轉為值語義,至少從抽象的角度看起來是這樣。
?
智能指針是解決了以上的問題嗎?
1. 因為智能指針是值語義的,所以保證不發生內存泄露和重復釋放。
2. 智能指針執行默認初始化和智能指針一定在對象銷毀之前銷毀,所以不可能出現野指針。
?
?