pimpl idiom struct memory leak

时间:2011-03-17 15:01:12

标签: qt boost memory-leaks pimpl-idiom

我们在课堂上使用了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()struct 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都是托管的。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

也许MyClass的实例被释放而没有被正确删除?例如,如果使用placement new将它们分配到某处,那么它们就不会被报告为单独泄漏,但是当它们的内存被释放时它们也不会被自动销毁。

答案 1 :(得分:1)

看起来确实应该有效..

我觉得奇怪的是泄漏的大小,只有48个字节。

我得出的结论是 MyClassImpl 结构被释放了,但其中的某些内容却没有。如果整个结构泄漏,泄漏将比48字节大很多。

但是,我仍然可以在该代码中找不到任何错误。

获取Visual Leak Detector以增强您的调试,它是免费的。

http://vld.codeplex.com/