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
};

不瞭解上述C++關鍵字移步此處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章