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. これが行うことは、に変換できるポインターを作成し、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 ドキュメント

于 2015-07-18T06:13:31.553 に答える
0

I believe this is exactly the scenario in this example: https://visualstudiomagazine.com/articles/2012/10/19/circular-references.aspx

This is a cyclic reference, and the solution is to have one of the pointers be a weak pointer. Although the article is for C++11's implementation of shared and weak pointers, boost also has a weak pointer for the exact same reason.

于 2015-07-18T05:13:06.700 に答える
0

son破棄されると、childrenオブジェクトの参照カウントは減少しますが、オブジェクトの参照カウントは減少parentしません。これは、childrenを含むオブジェクトがparent_ptr破棄されていないためです (参照カウントが 0 ではなく 1 であるため)。

同様に、fatherが破棄されると、parentオブジェクトの参照カウントは減少しますが、を含むオブジェクトが破棄されていないため (参照カウントが 0 ではなく 1 であるため) 、オブジェクトの参照カウントは減少childrenしません。parentchildren_ptr

于 2015-07-18T05:19:15.457 に答える