程式使用new
從堆(自由儲存區)分配記憶體,在不需要時,應使用delete
將其釋放。這個記憶體管理過程由程式設計師控制,記憶體洩露是困擾c/c++程式設計師的一大難題。,c++11中引入了智慧型指標的概念,方便管理堆記憶體。使用普通指標,容易造成堆記憶體洩露(忘記釋放)、二次釋放、程式發生異常時記憶體洩露等問題等,使用智慧型指標能更好的管理堆記憶體。
在c++11中摒棄了auto_ptr(在 c++ 17 中被移除),新增三種智慧型指標:
shared_ptr
、unique_ptr
都有乙個explicit
建構函式,因此不能自動將指標轉換為智慧型指標物件,必須顯式呼叫。
4.8.2
explicit shared_ptr(_tp1* __p)
: __shared_ptr<_tp>(__p)
explicit unique_ptr(pointer __p) noexcept
: _m_t(__p, deleter_type())
std::shared_ptr
是通過指標保持物件共享所有權的智慧型指標。shared_ptr
的目標非常簡單:多個指標可以同時指向乙個物件。下列情況之一出現時銷毀物件並解分配其記憶體:
int *p_int = new int;
shared_ptrsptr1(p); // ok
shared_ptrsptr2 = sptr1; // ok 引用計數+1
shared_ptrsptr3 = p_int; // error!!!
shared_ptrsptr1 = make_shared(100); // ok 使用 make_shared
shared_ptr
預設呼叫delete
釋放關聯的資源。如果使用者採用乙個不一樣的析構策略時,他可以自由指定構造這個shared_ptr
的策略。如下:當離開作用域時,預設的析構函式呼叫delete
釋放資源。實際上,我們應該呼叫delete
來銷毀這個陣列。
class test ;
void main()
使用者可以通過呼叫乙個函式,例如乙個lamda 表示式,來指定乙個通用的釋放步驟。
shared_ptrsptr1(new test[5], [ ](test* p) );
不要用乙個原始指標初始化多個shared_ptr
,否則會造成二次釋放同一記憶體。
void main()
如上,直接使用原始指標初始化多個shared_ptr
,使用時,智慧型指標相互間不知道彼此的存在。p1、p2儲存在棧上,程式結束時,首先 p2 死亡時引用計數為 0 ,釋放掉 ptr 。接著 p1 死亡,p1 記錄的引用計數也為 0 。再次對物件進行釋放,crash !!!。
引用計數是一種便利的記憶體管理機制,但它有乙個很大的缺點,那就是不能管理迴圈引用的物件。
class parent
public:
shared_ptrm_child;
};class child
public:
shared_ptrm_parent;
}void main()
兩個物件的引用計數都是 2 。當p_child
離開作用域時,子類物件引用計數 -1 (值為1)。當p_parent
離開作用域時,父類物件引用計數 -1 (值為1)。兩個智慧型指標生命期都結束了,但是物件記憶體卻都沒得到釋放!!!
【解決迴圈引用】
為了解決迴圈引用,c++
提供了另外一種智慧型指標:weak_ptr
。
std::weak_ptr
是一種智慧型指標,它對被std::shared_ptr
管理的物件存在非擁有性(「弱」)引用。在訪問所引用的物件前必須先轉換為std::shared_ptr
。
強引用:被引用的物件活著,這個引用就存在。只要有乙個強引用存在,這個物件就不能被釋放。
弱引用:弱引用不修改物件的引用計數,意味這弱引用它並不對物件的記憶體進行管理,在功能上類似於普通指標,然而乙個比較大的區別是,弱引用能檢測到所管理的物件是否已經被釋放,從而避免訪問非法記憶體。
class parent
public:
weak_ptrm_child;
};class child
public:
weak_ptrm_parent;
}
std::unique_ptr
是通過指標占有並管理另一物件,並在unique_ptr
離開作用域時釋放該物件的智慧型指標。
在下列兩者之一發生時用關聯的刪除器釋放物件:
unique_ptr
的建立方法和shared_ptr
一樣,除非建立乙個指向陣列型別的unique_ptr
。unique_ptr
提供了建立陣列物件的特殊方法,當指標離開作用域時,呼叫delete
代替delete
。當建立unique_ptr
時,這一組物件被視作模板引數的部分。這樣,程式設計師就不需要再提供乙個指定的析構方法
unique_ptr
提供乙個release()
的方法,釋放所有權。release
和reset
的區別在於,release
僅僅釋放所有權但不釋放資源,reset
釋放所有權同時也釋放資源。
C 11智慧型指標
本文介紹c 的四種智慧型指標,其中後三種是c 11新增加的,auto ptr已被棄用。要編譯c 11,需要安裝g 4.8 sudo add apt repository ppa ubuntu toolchain r test sudo apt get update sudo apt get inst...
c 11 智慧型指標
如果在程式中使用new從堆 自由儲存區 分配記憶體,等到不需要時,應使用delete將其釋放。c 引入了智慧型指標auto ptr,以幫助自動完成這個過程。c 11摒棄了auto ptr,並新增了三種智慧型指標 unique ptr,shared ptr,weak ptr。一.auto ptr,un...
c 11 智慧型指標
首先來看shared ptr,先貼一小部分vs2013裡的實現 template class shared ptr template class shared ptr public ptr base ty template explicit shared ptr ux px template cla...