2016-04-17 16 views
2

リンクリストにunique_ptrまたはshared_ptrを使用する必要がありますが、まだメモリリークが発生しています。この場合、すべてのメンバーデータをpublicとしています。リンクされたリストに最初の時間を挿入してもメモリリークは発生しませんが、forループが継続するたびに、オブジェクトをリンクリストに挿入するたびに、デバッガはより多くのメモリリークを示します。非常に多くのメモリリークを引き起こす可能性があるのはわかりません。それは共有されたptrsのいくつかによって引き起こされる可能性がありますか?C++リンクリスにデータを挿入するとメモリリークが発生する

template <typename T> 
    class Node 
    { 
    public: 
     T data; 
     shared_ptr<Node<T>> next; 
     shared_ptr<Node<T>> prev; 

    public: 
     Node() { next = NULL; prev = NULL; data = 0; } 
     Node(T value) { next = NULL; prev = NULL; data = value; } 
     T getData() { return data; } 

    }; 

    template <typename T> 
    class DoubleLinkedList 
    { 
    public: 
     shared_ptr<Node<T>> head; 
     shared_ptr<Node<T>> tail; 
    public: 
     DoubleLinkedList() 
    { 
     head = NULL; 
     tail = NULL; 
     total = 100; 
     for (int i = 0; i < total; i++) 
     { 
      Insert(objectgetsinsertedhere); 
     } 
    } 


void Insert(T data) 
{ 
    shared_ptr<Node<T>> rover = NULL; 
    T value(data); 
    if (head == NULL) 
    { 
     head = make_shared<Node<T>>(data); 
     tail = head; 
    } 
    else 
    { 
     shared_ptr<Node<T>> nu = make_shared<Node<T>>(data); 
     nu->prev = tail; 
     if (head == tail) 
      head->next = nu; 
     tail->next = nu; 
     tail = nu; 
    } 
} 
}; 

EDIT:これは、デバッガがメモリリークとして示す内容の一部です。

Detected memory leaks! 
Dumping objects -> 
{211} normal block at 0x005CF798, 8 bytes long. 
Data: <x \  > 78 98 5C 00 00 00 00 00 
{210} normal block at 0x005CF258, 8 bytes long. 
Data: <\ \  > 5C 98 5C 00 00 00 00 00 
{209} normal block at 0x005CF1B0, 8 bytes long. 
Data: <@ \  > 40 98 5C 00 00 00 00 00 
{205} normal block at 0x005C9830, 136 bytes long. 
Data: <H    > 48 A9 0C 00 01 00 00 00 01 00 00 00 CD CD CD CD 
{191} normal block at 0x005CF3A8, 8 bytes long. 
Data: < \  > A8 DB 5C 00 00 00 00 00 
{190} normal block at 0x005CF0D0, 8 bytes long. 
Data: < \  > 8C DB 5C 00 00 00 00 00 
{189} normal block at 0x005CF060, 8 bytes long. 
Data: <p \  > 70 DB 5C 00 00 00 00 00 
{185} normal block at 0x005CDB60, 136 bytes long. 
Data: <H    > 48 A9 0C 00 01 00 00 00 01 00 00 00 CD CD CD CD 
Object dump complete. 
+0

デバッガはどのような報告をしていますか? (実際にはメモリがリークしているのか、それとも単に予想していたより多くのメモリを検出しただけなのでしょうか?)そうであれば、shared_ptrがポインターを管理し、同じオブジェクト。 –

+0

これは、ダンプするオブジェクト - > {211} 0x005CF798の8バイトの通常ブロックのように見えるものです。 {189} 0x005CF060の通常ブロック、8バイト長。 データ:

70 DB 5C 00 00 00 00 136バイト長の0x005CDB60の{185}通常ブロック。 データ: 48 A9 0C 00 01 00 00 01 00 00 00 CD CD CD CD オブジェクトのダンプ完了。 – Mark

答えて

2

問題は共有ポインタに所有権のサイクルがあることです。これにより、リンクされたリスト自体が破棄された後でも、少なくとも1人の所有者が常に存在するため、メモリが自動的に解放されない場所になります。これに対処する1つの方法は、次のポインタの共有ポインタだけを使用することです。ただし、prevポインタは使用しないでください。

template <typename T> 
class Node 
{ 
    public: 
    T data; 
    shared_ptr<Node<T>> next; 
    Node<T> *prev; 

    public: 
    Node() { next = NULL; prev = NULL; data = 0; } 
    Node(T value) { next = NULL; prev = NULL; data = value; } 
    T getData() { return data; } 

}; 

これはオーナーシップサイクルを防止します。リストは、ヘッドを所有し、ヘッドは、第2の要素を所有する。リストが破壊されると、ヘッドの所有者がないので、ヘッドが破壊され、2番目の要素の所有者がいないので、

+0

残念ながら、私は 'unique_ptr'または' shared_ptr'のどちらか一方しか使用できません。これに対処する別の方法は、前のポインタのための一意のポインタと次のポインタのための共有ポインタを使用することだと思いますか? – Mark

+0

また、2つの異なるポインタに変更すると、ノードを挿入する際にエラーが発生します。たとえば、「nu-> prev = tail;」は、「shared_ptrをノード *に変換できません」というエラーを返します。 – Mark

+0

デストラクタを書く。 – Thomas

関連する問題