pimpl 习语结构内存泄漏

发布于 2024-10-24 05:03:49 字数 1448 浏览 2 评论 0原文

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

We are using the pimpl idiom in our classes. The pimpl struct is declared in the class which contains the pimpl pointer like so:

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

The implementation for the pimpl is in a seperate file called MyClassImpl.cpp
For example:

    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()
            {
            }
        };

In the constructor of a class that contains a pimpl pointer, I would have in the member variable initialization list something like

m_Impl(new MyClassImpl())

Now, we have enabled memory leak detection in our source code like so:

// 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

I am finding that when the program exits, memory leaks are reported for the 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 

I don't understand why since the m_Impl is a boost::scoped_ptr and the QString, QVariant, and shared_ptr are all managed. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷雾森÷林ヴ 2024-10-31 05:03:49

它看起来确实应该可以工作。

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

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

但我仍然找不到该代码的错误。

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

http://vld.codeplex.com/

It does look like it should work..

What i find odd is the size of the leak, only 48 bytes.

I'd draw the conclusion that the MyClassImpl struct is freed, but something in it, isn't. Should the entire struct leak, the leak would be a lot bigger than 48 bytes.

But still, I can find no fault in that code.

Get Visual Leak Detector to enhance your debugging, it's free.

http://vld.codeplex.com/

请你别敷衍 2024-10-31 05:03:49

也许 MyClass 的实例在没有被正确删除的情况下被释放?例如,如果使用新的放置将它们分配到某个地方,那么它们不会被报告为单独泄漏,但在释放内存时它们也不会被自动销毁。

Perhaps instances of MyClass are being freed without being properly deleted? If, for example, they're being allocated somewhere using placement new, then they wouldn't be reported as individually leaking, but neither would they be automatically destructed when their memory was released.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文