auto_ptr智能指针使用总结

本文详细探讨了智能指针auto_ptr的使用限制和潜在风险,包括所有权转移、赋值操作、数组指针管理、容器管理等方面的问题,并提供了安全使用的建议。通过实验证明了不当使用可能导致的野指针和内存泄露等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结:
  1).auto_ptr只能作为常量来保护,建议使用boost库的scoped_ptr就足够了,不要使用auto_ptr进行赋值和容器管理。
  2).对于需要对智能指针进行赋值\函数传递\容器管理\对象数组指针类型的操作,使用boost的shared_ptr,因为它使用了引用计数,否则使用auto_ptr只能对auto_ptr的引用或地址操作才是安全的。

使用auto_ptr需要注意的:
 1.不允许两个智能指针指向同一个对象,否则会导致删除时候删到野指针。
 2.不要进行智能指针赋值操作,否则所有权将进行传递,除非确定pAutoA以后不会再需要了。
 3.函数间传递无论是函数参数还是返回值,不能使用智能指针,若一定要使用只能用智能指针引用或地址,使用时候注意pThreeAutoA也是有&符号的,传递要非常小心。
4.指向数组,智能指针释放的时候只是delete没有delete[],导致隐性的严重的内存泄露。
5.STL容器管理指针指针不可以,但是管理智能指针的地址是可以的,但是这么做中间改变了智能指针也会悲剧。

测试代码:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class A
{
public:
 void SetNum(int num)
 {
  m_nNum = num;
 }
 void Display()
 {
  cout<<"m_nNum value:"<<m_nNum<<endl;
 }
private:
 int m_nNum;
};

// 智能指针传递,需要使用常量引用或者常量指针在函数之间传递
const auto_ptr<A>& TransferAutoPtrByReference(const auto_ptr<A> &p)
{
 return p;
}

const auto_ptr<A>* TransferAutoPtrByPtr(const auto_ptr<A> *p)
{
 return p;
}


int main()  
{  
 A *pObj = new A;
 auto_ptr<A> pAutoA(pObj);
 //auto_ptr<A> pAutoA2(pObj); // 1.不允许的,两个智能指针指向同一个对象会导致删除时候删到野指针
 pAutoA->SetNum(10);
 pAutoA->Display();

 auto_ptr<A> pSecondAutoA = pAutoA; // 2.不要进行赋值操作,否则所有权将进行传递,除非确定pAutoA以后不会再需要了
 /*if(pAutoA._Myptr == NULL) // pAutoA._Myptr变为了空但是是私有成员,pAutoA是野指针
 {
  pAutoA->SetNum(100);
  pAutoA->Display();
 }*/
 pSecondAutoA->Display();
 const auto_ptr<A> &pThreeAutoA = TransferAutoPtrByReference(pSecondAutoA);// 3.使用时候注意pThreeAutoA也是有&符号的,传递要非常小心
 pSecondAutoA->Display();
 pThreeAutoA->Display();

 const auto_ptr<A> *pFourAutoA = TransferAutoPtrByPtr(&pSecondAutoA);// 使用时候注意pFourAutoA是智能指针的地址,传递要非常小心
 pSecondAutoA->Display();
 (*pFourAutoA)->Display();

 A *pArrayA = new A[10];
 auto_ptr<A> pArrayAutoPtr(pArrayA);// 4.指向数组,智能指针释放的时候只是delete没有delete[],导致隐性的严重的内存泄露
 pArrayAutoPtr->SetNum(1);
 pArrayAutoPtr->Display();

 vector<auto_ptr<A>*> vecPtrA;// 5.STL容器管理指针指针不可以,但是管理智能指针的地址是可以的,但是这么做中间改变了智能指针也会悲剧
 vecPtrA.push_back(&pSecondAutoA);
 vector<auto_ptr<A>*>::iterator itrA = vecPtrA.begin();
 for(; itrA != vecPtrA.end(); ++itrA)
 {
  (*(*itrA))->SetNum(999);
  (*(*itrA))->Display();
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值