Qt pimpl惯用结构内存泄漏

Qt pimpl惯用结构内存泄漏,qt,boost,memory-leaks,pimpl-idiom,Qt,Boost,Memory Leaks,Pimpl Idiom,我们在课堂上使用pimpl习语。pimpl结构在包含pimpl指针的类中声明,如下所示: struct MyClassImpl; friend struct MyClassImpl; boost::scoped_ptr<MyClassImpl> m_Impl; 现在,我们在源代码中启用了内存泄漏检测,如下所示: // Memory leaks detection in Visual Studio #if defined (_WIN32) && defined (_D

我们在课堂上使用pimpl习语。pimpl结构在包含pimpl指针的类中声明,如下所示:

struct MyClassImpl;
friend struct MyClassImpl;
boost::scoped_ptr<MyClassImpl> m_Impl;
现在,我们在源代码中启用了内存泄漏检测,如下所示:

// 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
//Visual Studio中的内存泄漏检测
#如果已定义(_WIN32)和已定义(_DEBUG)
#定义\u CRTDBG\u映射\u ALLOC
#包括
#定义新的(正常块、文件、线)
#恩迪夫
我发现当程序退出时,MyClassImpl()结构m_Impl(新的MyClassImpl())会报告内存泄漏:

。\..\src\MyClass.cpp(29):{290222}0x0B9664E0处的正常块,48字节长。
数据:58 1C 6C 03 56 00 00 59 40

我不明白为什么m_Impl是boost::scoped_ptr,QString、QVariant和shared_ptr都是管理的。有什么想法吗?

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

看起来确实应该可以工作

我发现奇怪的是泄漏的大小,只有48字节

我的结论是MyClassImpl结构已被释放,但其中的某些内容未被释放。如果整个结构泄漏,泄漏将远远大于48字节

但是,我仍然不能在代码中找到错误

获取可视泄漏检测器以增强您的调试,这是免费的


您能解释一下,您所说的未被正确删除而释放是什么意思吗?我仔细检查了在销毁包含类MyClass时是否调用了MyClassImpl的构造函数。是否作用域指针仍然没有被破坏?我的意思是,可以使用一种称为“placement new”的特殊形式的new在一块原始内存中构造MyClass的实例,即“void*”。释放内存后,内存中的对象将不会自动销毁。如果发生这种情况,则包含MyClass实例的void*块不会泄漏,但MyClassImpl会泄漏。这只是一个理论——我相信还有其他可能出错的事情。你确定在调用exit之前调用了MyClass析构函数吗?如果你想获得有关泄漏的更好信息,请获取可视泄漏检测器。共享的\u ptr可能是引用循环的一部分,并阻止释放内容。如果没有其他类的定义,是不可能分辨出来的。在我看来,QVariant似乎是罪魁祸首。里面有什么?山姆:是的,我肯定我的类析构函数被称为sorry,还没有,我在工作中遇到了一些其他问题,这件事的优先级较低。我会更新,但一旦我进一步检查。
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
..\..\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