0

ここでメモリリークが発生する理由がわかりません。アドバイスをいただければ幸いです。プロセスが終了する前に、シングルトン オブジェクトを削除することになっている静的メンバー関数である destroy() を呼び出すことに注意してください。

関連するコードと valgrind のメッセージは次のとおりです。

Manager.h:
class Manager {
public:
    // Constructor/destructor
    static Manager * instance();
    static void destroy();
    ~Manager();
        // Bunch of functions that I didn't write here

private:
    Manager();
    static Manager * _singleton; 
        // Bunch of fields that I didn't write here
};

Manager.cpp:
#include "Manager.h"

Manager * Manager::_singleton = NULL;

Manager * Manager::instance() {
    if (_singleton == NULL) {
            _singleton = new Manager();
        }
    return _singleton;
}

void Manager::destroy()
{
    delete _singleton;
    _singleton = NULL;
}

/*
 * Destructor
 */
Manager::~Manager() {
    // Deleting all fields here, memory leak is not from a field anyway
}

valgrind のレポートは次のとおりです。

==28688== HEAP SUMMARY:
==28688==     in use at exit: 512 bytes in 1 blocks
==28688==   total heap usage: 12 allocs, 11 frees, 10,376 bytes allocated
==28688== 
==28688== 512 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28688==    at 0x4C27297: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28688==    by 0x4014CE: Manager::Manager() (Manager.cpp:33)
==28688==    by 0x401437: Manager::instance() (Manager.cpp:15)
==28688==    by 0x4064E4: initdevice(char*) (outputdevice.cpp:69)
==28688==    by 0x406141: main (driver.cpp:21)
==28688== 
==28688== LEAK SUMMARY:
==28688==    definitely lost: 512 bytes in 1 blocks
==28688==    indirectly lost: 0 bytes in 0 blocks
==28688==      possibly lost: 0 bytes in 0 blocks
==28688==    still reachable: 0 bytes in 0 blocks
==28688==         suppressed: 0 bytes in 0 blocks

なぜこのリークがあるのですか?私はで削除_singletonしますdestroy()

私が言ったように、私はどんな助けにも感謝します、ありがとう!

4

1 に答える 1

6

ここで注意すべきことがいくつかあります。最も明白なのは、いつ電話するかですManager::destroy。2つ目は、メモリvalgrind が不平を言っているように見えることです。これは、のコンストラクタに割り当てられて Managerいますが、これは表示されていません。エラーメッセージを信じることができれば(そして、valgrindだまされる可能性はありますが、この点で一般的に信頼できることがわかりました)、メモリへのポインタは残っていません。オブジェクトのフィールドの1つを削除していないか、オブジェクトがコンストラクターにメモリを割り当て、フィールドに保存していません。

最後に、通常はシングルトンを破壊しない方が良い方法です。シングルトンイディオムの全体的な目的は、初期化の問題の順序を回避することです(少なくとも、C ++では、オブジェクトの静的インスタンスを宣言するだけで十分です)。オブジェクトを破棄すると、破棄の問題が発生する可能性があります。破棄しないと、valgrindメモリリークの可能性について警告されます(「完全に失われた」わけではありません)。警告を無視するか、フィルターで除外することができます。

于 2012-05-15T08:05:36.323 に答える