在以下代码内存泄漏发生时,我对此表示怀疑。在测试()乐趣:
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class parent;
class children;
typedef boost::shared_ptr<parent> parent_ptr;
typedef boost::shared_ptr<children> children_ptr;
class parent
{
public:
~parent() { std::cout <<"destroying parent\n"; }
public:
children_ptr children;
};
class children
{
public:
~children() { std::cout <<"destroying children\n"; }
public:
parent_ptr parent;
};
void test()
{
parent_ptr father(new parent());
children_ptr son(new children);
father->children = son;// parent_ptr_count=1, children_ptr_count=2
son->parent = father;// parent_ptr_count=2, children_ptr_count=2
//1,2,3 See the note below
}
void main()
{
std::cout<<"begin test...\n";
test();
std::cout<<"end test.\n";
}
// childern_ptr从堆栈弹出,我认为childern_ptr_count--和parent_ptr_count -
// parent_ptr从堆栈中弹出,我认为childern_ptr_count--和parent_ptr_count -
//但事实上,它没有那样做,为什么?
我希望有人可以帮助我,非常感谢你。
答案 0 :(得分:0)
我相信这正是本例中的情景:https://visualstudiomagazine.com/articles/2012/10/19/circular-references.aspx
这是一个循环引用,解决方案是让其中一个指针成为弱指针。虽然这篇文章是针对C ++ 11的共享和弱指针的实现,但出于完全相同的原因,boost也有一个弱指针。
答案 1 :(得分:0)
当son
被销毁时,children
对象的引用计数会下降,但parent
对象的引用计数不会,因为children
对象包含parent_ptr
未被销毁(因为它的引用计数为1,而不是0)。
同样,当father
被销毁时,parent
对象的引用计数会下降,但children
对象的引用计数不会,因为parent
包含children_ptr
的对象未被销毁(因为其引用计数为1,而不是0)。
答案 2 :(得分:0)
与其他答案建议一样,您已创建a circular reference。
这是一个解决方案。当指针指向彼此时,使用weak_ptr
通常很有用。这样做会使指针成为shared_ptr
,当它不是shared_ptr
时,它不会增加引用计数,因此允许对象被销毁。
以下是一个例子:
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class parent;
class children;
typedef boost::shared_ptr<parent> parent_ptr;
typedef boost::shared_ptr<children> children_ptr;
typedef boost::weak_ptr<parent> parent_weak_ptr;
typedef boost::weak_ptr<children> children_weak_ptr;
class parent
{
public:
~parent() { std::cout <<"destroying parent\n"; }
public:
children_weak_ptr children;
};
class children
{
public:
~children() { std::cout <<"destroying children\n"; }
public:
parent_weak_ptr parent;
};
void test()
{
parent_ptr father(new parent());
children_ptr son(new children);
father->children = son;// parent_ptr_count=1, children_ptr_count=1
son->parent = father;// parent_ptr_count=1, children_ptr_count=1
}
void main()
{
std::cout<<"begin test...\n";
test();
std::cout<<"end test.\n";
}
使用此代码,子级和父级将被销毁,并且他们可以使用lock()
上的weak_ptr
函数相互访问,将其转换为shared_ptr
。这是一些文档:
boost::weak_ptr
docs
std::weak_ptr
docs