1

私たちはクラスで pimpl イディオムを使用しています。pimpl 構造体は、次のように pimpl ポインターを含むクラスで宣言されます。

struct MyClassImpl;
friend struct MyClassImpl;
boost::scoped_ptr<MyClassImpl> m_Impl;

pimpl の実装は、MyClassImpl.cpp という別のファイルにあります。次に例を示します。

    struct MyClass::MyClassImpl
        {
            QString m_Name;                             
            int m_Type;                                 
            double m_Frequency;                         
            int m_DefaultSize;                          
            QVariant m_DefaultValue;
                 boost::shared_ptr<SomeOtherClass> m_SomeOtherClass;                    

            ~MyClassImpl()
            {
            }
        };

pimplポインターを含むクラスのコンストラクターでは、メンバー変数の初期化リストに次のようなものがあります

m_Impl(new MyClassImpl())

これで、次のようにソース コードでメモリ リーク検出を有効にしました。

// Memory leaks detection in Visual Studio
#if defined (_WIN32) && defined (_DEBUG)
#   define _CRTDBG_MAP_ALLOC
#   include <crtdbg.h>
#   define new new(_NORMAL_BLOCK ,__FILE__, __LINE__) 
#endif

プログラムが終了すると、MyClassImpl() 構造体 m_Impl(new MyClassImpl()) でメモリ リークが報告されることがわかりました。

..\..\src\MyClass.cpp(29) : {290222} normal block at 0x0B9664E0, 48 bytes long.
 Data: <X l V         Y@> 58 1C 6C 03 56 00 00 00 00 00 00 00 00 00 59 40 

m_Impl は boost::scoped_ptr であり、QString、QVariant、および shared_ptr はすべて管理されているため、その理由がわかりません。何か案は?

4

2 に答える 2

1

それはうまくいくように見えます..

私が奇妙だと思うのは、リークのサイズで、わずか 48 バイトです。

MyClassImpl構造体は解放されているが、その中の何かが解放されていないという結論を導き出します。構造体全体がリークした場合、リークは 48 バイトよりもはるかに大きくなります。

それでも、そのコードに問題は見つかりません。

Visual Leak Detector を入手して、デバッグを強化してください。無料です。

http://vld.codeplex.com/

于 2011-03-18T08:52:21.820 に答える
1

MyClass のインスタンスが適切に削除されずに解放されている可能性がありますか? たとえば、placement new を使用してどこかに割り当てられている場合、個別にリークしていると報告されることはありませんが、メモリが解放されたときに自動的に破棄されることもありません。

于 2011-03-17T15:09:30.447 に答える