码迷,mamicode.com
首页 > 其他好文 > 详细

循环引用-智能指针的死穴之一

时间:2015-04-08 13:14:57      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:智能指针   c++   share_ptr   

       智能指针的实现思路也体现了C++基于对象的原则,对象应该为自己管理的资源负责,包括资源的分配与释放,而且最好将资源的释放与分配搞的自动化一点,典型的实现方法就是在构造函数里分配资源,在析构函数里释放资源,这样当其他程序员在使用这个对象时,该对象的资源问题几乎不用额外的操心,即优雅又方便

        然后如此完美的东西,也有其不容忽视的地方,直接上代码:

// share_ptr.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "common_class.h"

class B;

class A{

private:
	typedef tr1::shared_ptr<B> Item_Type;
public:
	explicit A(){};
	virtual ~A(){};

public:
	void SetB(const Item_Type ptr_B){m_B = ptr_B;}
private:
	Item_Type m_B;
};

class B{

private:
	typedef tr1::shared_ptr<A> Item_Type;
public:
	explicit B(){};
	virtual ~B(){};
public:
	void SetA(const Item_Type ptr_A){m_A = ptr_A;}
private:
	Item_Type m_A;
};
int _tmain(int argc, _TCHAR* argv[])
{
	size_t count = 100000;
	getchar();//查看内存状态
	while(count--)
	{
		//new出来的A的引用计数此时为1
		shared_ptr<A> a(new A);
		//new出来的A的引用计数此时为1
		shared_ptr<B> b(new B);

		//B的引用计数增加为2
		a->SetB(b);
		//A的引用计数增加为2
		b->SetA(a);
	}
	getchar();//查看内存状态

	//b先出作用域,B的引用计数减少为1,不为0,所以堆上的B空间没有被释放,
	//且B持有的A也没有机会被析构,A的引用计数也完全没减少
	//a后出作用域,同理A的引用计数减少为1,不为0,所以堆上A的空间也没有被释放
	return 0;
}

 

两次查看内存资源状态结果

技术分享技术分享

结果可知:内存增加了几乎20M,更何况我定义的两个对象本身不怎么占资源,如果内部维护了几个list,结果可想而知!

A和B都互相指着对方吼,“放开我的引用!“,“你先发我的我就放你的!”,于是悲剧发生了。

所以在使用基于引用计数的智能指针时,要特别小心循环引用带来的内存泄漏,循环引用不只是两方的情况,只要引用链成环都会出现问题。当然循环引用本身就说明设计上可能存在一些问题,如果特殊原因不得不使用循环引用,那可以让引用链上的一方持用普通指针(或弱智能指针weak_ptr)即可.

 

循环引用-智能指针的死穴之一

标签:智能指针   c++   share_ptr   

原文地址:http://blog.csdn.net/oshirdey/article/details/44938187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!