0

在以下代码中发生内存泄漏,我对此表示怀疑。在 test() 乐趣中:

#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";
}
  1. // childern_ptr 从堆栈中弹出,我认为 childern_ptr_count-- 和 parent_ptr_count--

  2. // parent_ptr 从堆栈中弹出,我认为 childern_ptr_count-- 和 parent_ptr_count--

  3. // 但实际上它并没有这样做,为什么?

我希望有人可以帮助我,非常感谢。

4

3 回答 3

0

就像其他答案所暗示的那样,您已经创建了一个循环引用

这是一个解决方案。当您有指向彼此的指针时,使用weak_ptr. 这样做的目的是创建一个可以变成 a 的指针,shared_ptr当它不是 a 时,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 文档

std::weak_ptr 文档

于 2015-07-18T06:13:31.553 回答
0

我相信这正是本示例中的场景:https ://visualstudiomagazine.com/articles/2012/10/19/circular-references.aspx

这是一个循环引用,解决方案是让其中一个指针成为弱指针。虽然这篇文章是针对 C++11 的共享指针和弱指针的实现,但出于完全相同的原因,boost 也有一个弱指针。

于 2015-07-18T05:13:06.700 回答
0

son被销毁时,children对象的引用计数会下降,但对象的引用计数parent不会,因为children包含 的对象parent_ptr没有被销毁(因为它的引用计数是 1,而不是 0)。

同样,当father被销毁时,parent对象的引用计数会下降,但对象的引用计数children不会,因为parent包含 的对象children_ptr没有被销毁(因为它的引用计数是 1,而不是 0)。

于 2015-07-18T05:19:15.457 回答