почему утечка памяти при использовании циклической ссылки в boost :: 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;

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. // но на самом деле это не так, почему?

Я надеюсь, что кто-то может мне помочь, большое спасибо.

0

Решение

Я считаю, что это именно тот сценарий в этом примере: https://visualstudiomagazine.com/articles/2012/10/19/circular-references.aspx

Это циклическая ссылка, и решение состоит в том, чтобы один из указателей был слабым указателем. Хотя статья предназначена для реализации общих и слабых указателей в C ++ 11, у boost также есть слабый указатель по той же причине.

0

Другие решения

когда son уничтожен, счетчик ссылок для children объект падает, но счетчик ссылок для parent объект не, потому что children объект, который содержит parent_ptr не был уничтожен (потому что его счетчик ссылок равен 1, а не 0).

Аналогично, когда father уничтожен, счетчик ссылок для parent объект падает, но счетчик ссылок для children объект не, потому что parent объект, который содержит children_ptr не был уничтожен (потому что его счетчик ссылок равен 1, а не 0).

0

Как и в других ответах, вы создали круговая ссылка.

Вот решение. Когда у вас есть указатели, указывающие друг на друга, часто бывает полезно использовать 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 документы

std::weak_ptr документы

0
По вопросам рекламы [email protected]