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
};
经验分享 程序员 微信小程序 职场和发展