C++ 裸指針和智能指針
裸指針的缺陷及實例演示
忘記釋放指針指向的資源
class Menory
{
private:
int* m_p;
public:
Menory()
{
m_p = new int[5];
}
~Menory()
{
}
int* getmemory()
{
return m_p;
}
};
int main()
{
int* p = nullptr;
{
Menory space = Menory();
p = space.getmemory();
}
return 0;
}
在主函數中 出了大括號的作用域後 調用了space的析構函數 但是析構函數中沒有delete掉p指向的自由存儲區中開闢的內存 該內存仍然是不可用狀態 導致了內存泄漏
代碼邏輯過早結束 導致釋放資源的代碼執行不到
int main()
{
int* p = new int[10];
if (true)
{
return 0;
}
delete[] p;
return 0;
}
在執行到if條件判斷後 進入條件判斷 程序直接退出 沒有執行到delete[] p語句
代碼運行過程中,代碼發生異常了,直接出當前函數棧幀了
導致釋放資源的代碼執行不到
int main()
{
int* p = new int[12];
try
{
throw 1;
throw "error";
}
catch (int i)
{
}
catch (char* str)
{
}
delete[] p;
}
拋出異常捕獲後 直接回退到上一個棧幀,不執行delete操作
通過裸指針,訪問對象時,無法判斷對象是否存活,還是已經析構掉了
int main()
{
Menory p1;
{
Menory data1 = Menory();
p1 = Menory();
}
cout << *p1.getmemory() << endl;
return 0;
}
p1所指向的Menory對象作用域在{}中 除了}自動調用p所指向的實例的析構函數,p所指向的實例已經被析構,但是裸指針不能發現。
多個指針指向同一塊內存釋放導致的失效指針的問題
int main()
{
int* p = new int[20];
int* p1 = p;
delete[] p1;
return 0;
}
p1和p指向同一塊內存 delete p1後p也就失效了 釋放p1指向的內存等同於釋放p指向的內存
智能指針的優勢
智能指針的智能二字,主要體現在用戶可以不關注資源的釋放,
因爲智能指針會幫你完全管理資源的釋放,任何情況下資源到期都會釋放
不帶引用計數的智能指針
C++庫中提供的不帶引用計數的智能指針主要包括:
auto_ptr,scoped_ptr,unique_ptr
auto_ptr
template<class _Ty>
class auto_ptr
{ // wrap an object pointer to ensure destruction
public:
typedef _Ty element_type;
explicit auto_ptr(_Ty * _Ptr = nullptr) noexcept
: _Myptr(_Ptr)
{ // construct from object pointer
}
/*這裏是auto_ptr的拷貝構造函數,
_Right.release()函數中,把_Right的_Myptr
賦爲nullptr,也就是換成當前auto_ptr持有資源地址
*/
auto_ptr(auto_ptr& _Right) noexcept
: _Myptr(_Right.release())
{ // construct by assuming pointer from _Right auto_ptr
}
_Ty * release() noexcept
{ // return wrapped pointer and give up ownership
_Ty * _Tmp = _Myptr;
_Myptr = nullptr;
return (_Tmp);
}
private:
_Ty * _Myptr; // the wrapped object pointer
};