簡體   English   中英

為什么在boost :: shared_ptr中使用循環引用時會發生內存泄漏

[英]why memory leak when use circular reference in boost::shared_ptr

在以下代碼發生內存泄漏時,我對此表示懷疑。 在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. //但實際上,它沒有這樣做,為什么呢?

希望有人能幫助我,非常感謝。

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

這是一個循環引用,解決方案是使指針之一為弱指針。 盡管本文是針對C ++ 11的共享指針和弱指針的實現,但出於完全相同的原因,boost也具有弱指針。

son被銷毀時, children對象的引用計數下降,但parent對象的引用計數卻沒有下降,因為包含parent_ptrchildren對象未被銷毀(因為其引用計數為1,而不是0)。

同樣,當father被銷毀時, parent對象的引用計數下降,但children對象的引用計數卻沒有下降,因為包含children_ptrparent對象未被銷毀(因為其引用計數為1,而不是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";
}

使用此代碼,子級和父級被銷毀,並且他們可以使用weak_ptr上的lock()函數相互訪問以將其轉換為shared_ptr 這是一些文檔:

boost::weak_ptr 文檔

std::weak_ptr 文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM