c++11之std::shared_ptr、std::weak_ptr的用法以及循环引用计数问题

shared_ptr指针

C++11引入了智能指针shared_ptr,自动释放内存,极大的避免了内部泄漏问题的发生。shared_ptr解决了该何时删除指针所指向的对象(释放内存)的问题,shared_ptr引入了引用计数,指向同一个资源的所有shared_ptr智能指针拥有同一个引用计数,当被管理的资源增加shared_ptr指针对象共享时,shared_ptr的引用计数加1,当这个shared_ptr智能指针生存期结束时,引用计数减1,当最后一个智能指针的生存期结束时,引用计数减少到0,资源被释放。

下面是一个循环引用导致内存泄漏的例子

#include <stdio.h>
#include <memory>
class A;
class B;
typedef std::tr1::shared_ptr<A> APtr;
typedef std::tr1::shared_ptr<B> BPtr; 

class A {
public:
  BPtr bptr;
  ~A () {
    printf ("A destructed\n");
  }
};

class B {
public:
  APtr aptr;
  ~B () {
    printf ("B destructed\n");
  }
};

void test()
{
	std::shared_ptr<A> ap(new A());
	std::shared_ptr<B> bp(new B());

	ap->bptr = bp;
	bp->aptr = ap;
}

int main () 
{
	test();
	return 0;
}

上面的结果是A类对象和B类对象均不会删除,存在内存泄漏,循环引用导致ap和bp的引用计数为2,离开test函数时,ap和bp的生存期结束,引用计数减为1,导致指针所指向的类对象均不会析构,解决的办法就是将A或B的任意一个成员变量给为weak_ptr。

通过weak_ptr解决循环应用导致内存泄漏问题

#include <stdio.h>
#include <memory>
class A;
class B;
typedef std::tr1::shared_ptr<A> APtr;
typedef std::tr1::weak_ptr<B> BPtr;  //这里改成weak_ptr

class A {
public:
  BPtr bptr;
  ~A () {
    printf ("A destructed\n");
  }
};

class B {
public:
  APtr aptr;
  ~B () {
    printf ("B destructed\n");
  }
};

void test()
{
	std::shared_ptr<A> ap(new A());
	std::shared_ptr<B> bp(new B());

	ap->bptr = bp;
	bp->aptr = ap;
}

int main () 
{
	test();
	return 0;
}

当给ap->bptr赋值时,即执行ap->bptr = bp,由于bptr是weak_ptr,不会增加引用计数,所以ap的引用计数还是为1,离开test函数后,bp的引用计数会减为0,其内部的aptr的引用计数会减为1,在ap离开作用域后,ap的引用计数减为0,A对象被析构,不会发生内存泄漏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值