C++内存管理之智能指针

使用C++,最重要的一块技能就是内存的分配和管理。这也是C/C++ 中陷阱最多的地方。说来惭愧,我曾经写过一个获取网卡信息的接口,有一个返回分支没有调用free函数释放资源,运行时间常了之后,进程占用的内存越来越大。后来自己总结,要避免这种错误的发生,一个是自身要检查好代码,可以使用其他辅助工具如 静态代码检查工具CppCheck 和 内存泄漏valgrid等。
对于JAVA开发,就不必花那么多精力去关心内存问题。C++ 在这块的改进最明显的就是引入了智能指针,不必再担心是否忘记释放内存。一些搞跨平台开发的项目对这个可能要求不高,因为工程可能要兼容很多平台,有些平台的C++运行环境未必支持指针,但这毕竟不是主流,智能指针还是要了解一下的。
我曾经写过一个函数追踪的类,大概功能是,在要追踪的函数里面声明一个追踪类对象,然后把函数名 __ FUNC_NAME __ 作为初始化参数传递进去。这个tracer类,内部只实现构造和析构。因为函数开始的时候,对象开始构造,函数结束之前销毁对象。在构造函数中,打印一句func_name 开始了,析构函数中打印一句, func_name结束了。这里面的一个原理,是栈变量离开作用域时,会自动销毁。智能指针本质上是一个对象,它重载了*和->运算符,在行为上和普通指针的使用相同。为了兼容不同类型,里面用到了模板技术。
STL提供的智能指针有四种,auto_ptr, unique_ptr, share_ptr, weak_ptr, 了解了他们之间的关系就很容易记住和使用。使用这四个指针,需要引入头文件

#include <memory>
using namespace std;
  1. auto_ptr实现了智能指针的基本功能,但是当右值时,会被剥夺资源,再次访问时,易出错。现在C++11,已明确废弃,不提倡使用了。
    auto_ptr<int> a1(new int(1));
    auto_ptr<int> a2 = a1;
    // get函数返回真正的指针
    if(a1.get() == NULL)
        cout << "a1 is null"<<endl;
    else
        cout<<*a1<<endl;

    if(a2.get() == NULL)
        cout << "a2 is null"<<endl;
    else
        cout<<*a2<<endl;
  1. unique_ptr 是解决了auto_ptr的问题,它不允许赋值给其他智能指针. unique_ptr独占资源所有权,离开作用域时,释放资源。
    unique_ptr<int> u1(new int(5));
    //unique_ptr<int> u2 = u1;  //error
    //unique_ptr<int> u3(u1);   //error
    cout<<*u1<<endl;
    auto us = make_unique<Simple>();// C++ 14
  1. shared_ptr 用来解决共享资源的情况,它内部采用了引用计数。
    shared_ptr<int> s1(new int(6));
    shared_ptr<int> s2 = s1;
    shared_ptr<int> s3(s1);
    cout<<*s1<<endl;
    cout<<*s2<<endl;
    cout<<*s3<<endl;
    cout<<s1.use_count()<<endl;//返回引用计数数量
  1. weak_ptr的引入是为了解决shared_ptr中两个或以上类相互包含,造成死锁,无法使引用计数归零的情况。weak_ptr并不会使引用数量增加。注意,weak_ptr不能直接调用成员函数,要使用lock() 返回一个shared_ptr智能指针,然后才可以调用成员函数。
class SampleB;
class SampleA
{
public:
    shared_ptr<SampleB> psb;
    void echo()
    {
        cout<<"I am SampleA"<<endl;
    }

    ~SampleA()
    {
        cout<<"~SampleA" << endl;
    }
};
class SampleB
{
public:
    //shared_ptr<SampleA> psa;
    weak_ptr<SampleA> psa;
    ~SampleB()
    {
        cout<<"~SampleB" << endl;
    }
};


int main()
{
    shared_ptr<SampleB> pb(new SampleB());
    shared_ptr<SampleA> pa(new SampleA());
    pb->psa = pa;
    pa->psb = pb;
    cout<<pb.use_count()<<endl;
    cout<<pa.use_count()<<endl;
    pb->psa.lock()->echo();
    return 0;
}

上面就是C++提供四个智能指针, 使用起来和普通指针相似,很容易上手。

auto_ptr,C++11 已废弃
shared_ptr,unique_ptr,weak_ptr C++11加入
make_unique C++14

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值