1

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?

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
Bizmarck
  • 2,663
  • 2
  • 33
  • 48
  • Are you sure the MyClass destructor is invoked prior to invoking exit? – Sam Miller Mar 18 '11 at 01:48
  • Get Visual Leak Detector if you want to get better info on the leak. – 0xbaadf00d Mar 18 '11 at 08:37
  • The shared_ptr might be part of a cycle of references and prevent stuff from being freed. It's impossible to tell without the definition of `SomeOtherClass` tho. – ltjax Mar 18 '11 at 08:59
  • That QVariant looks like the culprit to me. What's in it? – TonyK Mar 18 '11 at 10:16
  • Sam: yes I'm sure MyClass destructor is called – Bizmarck Mar 18 '11 at 16:18
  • Sam: yes I'm sure MyClass destructor is called justanothercoder: thanks I will try that out Itjax: SomeOtherClass is actually a validator class for the QVariant, I will check into it TonyK: QVariant contains some custom classes. Basically what I am taking away from this is there might be something in the struct that is leaking, so needs some further investigation. Thanks for all the feedback, will post what I find when I do ! – Bizmarck Mar 18 '11 at 16:24

2 Answers2

1

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.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • Can you explain, what do you mean by freed without being properly deleted? I double checked that the constructor for MyClassImpl is getting called when the containing class MyClass is destructed. Is it that the scoped pointer is still not destructed? – Bizmarck Mar 17 '11 at 15:21
  • I mean that it is possible to construct an instance of MyClass in a block of raw memory -- i.e., a "void *" -- using a special form of new called "placement new". When that memory is freed, the object in it will not be automatically destructed. If this were happening, the void * block containing the MyClass instance would not be leaked, but the MyClassImpl would. It's just a theory -- I'm sure there are other possible things that could go wrong. – Ernest Friedman-Hill Mar 17 '11 at 15:29
1

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/

0xbaadf00d
  • 2,535
  • 2
  • 24
  • 46
  • Sorry, not yet, I was sidetracked with some other issues at work and this took a lower priority. I WILL update though once I examine further. – Bizmarck Mar 29 '11 at 21:26