C++ 智能指针 野指针

野指针与智能指针

  1. 野指针指向了非法的内存区域,
  2. 典型的情况
    • 动态申请之后又释放的内存
    • 临时变量自动消亡之后原先的那块地址。
    • 错误的指针运算
    • 强制的指针类型转换
  3. 智能指针模板类
    • 一些动态分配的内存可能内存泄漏:1.可能忘记delete了 2.函数内部抛出了异常没有执行到delete语句。
    • 智能指针的思想是,将指针包装成一个对象;当指针析构时,在析构函数里释放所指向的内存空间。
    • 常见的智能指针模板有 auto_ptr(被c++11弃用), unique_ptr, shared_ptr, weak_ptr
    • 将new出来的地址赋值给智能指针,不需要人为delete,当智能指针析构时会自动delete。
    • 智能指针模板包含在头文件 <memory> 中。
  4. 智能指针基本操作:
    • 智能指针类接受指针作为(显式)构造函数参数,不能直接用指针赋值(也就是不能隐式类型转换)shared_ptr<int> p(new int(3)); \\ok p = new int(3)\\wrong
    • 智能指针对象可以:*解引用,->访问结构成员,赋值给兼容的指针变量,赋值给同类型智能指针。
    • 智能指针构造的参数必须要是堆内存(即动态分配出来的),否则析构时引起错误。
  5. 如何避免多次delete同一个内存位置?
    • 考虑这样的问题,下面的代码析构时是否会delete同一个内存两次
    auto_ptr<string> ps (new string ("hello world"));
    auto_ptr<string> p = ps;
    
    为了解决这个问题,智能指针有两种策略:
    • 建立 所有权 概念(auto_ptr, unique_ptr这样做),对于特定的对象,只能被一个智能指针对象拥有;智能指针的赋值操作会转让所有权。
      • 所有权被转让之后,就不能通过这个智能指针去访问对象。
      auto_ptr<string> p (new string ("hello world"));
      auto_ptr<string> q = p;    // p loses ownership
      cout << *p << endl;        // segmentation fault, 引用空指针
      
      • unique_ptr与auto_ptr的区别:上面的代码如果使用unique_ptr,第二行就无法通过编译。这个意义上,unique_ptr更安全。
      • 但是unique_ptr允许通过函数返回值来赋值,因为这里源智能指针是个右值。
      unique_ptr<string> func(const char* s){
          unique_ptr<string> temp (new string (s));
          return temp;
      }
      unique_ptr<string> p = func("Allowed uniquely");  // ok
      p = unique_ptr<string>(new string("hello world")) // ok
      unique_ptr<string> q = move(p);  // ok, 使用了move得到右值引用
      
    • 引用计数(shared_ptr这样做),维护这块内存被多少智能指针引用,只有最后一个对象析构时才会delete。
    • 如果希望指针用于数组,unique_ptr提供这样的方式,而shared_ptr, auto_ptr都不提供。这样创建的指针析构时会使用delete[]。
      std::unique_ptr<double []> p (new double[5]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值