Re: stl::string memory leak associated with polymorphism

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



Hi,

Thanks a lot! I did not know about this fact; however I should have
known.
I now just added
virtual ~Base() {}
and everything works fine. I would never have found out this on my own
:)

So if I understood it correctly, each class has a default-destructor
(which is NOT virtual) which deals with the clean-up of all member
variables. When using polymorphism, only the default destructor of Base
is called (because only the pointer to this type is available). By
making the default-destructor of Base virtual, polymorphim comes into
play and the destructor of Final is called instead (which in turn will
continue with the Base destructor). That's a beautiful concept - as
soon as one knows about it :))
(For others, here ist a link which explains the merits of the virtual
destructor: http://www.codersource.net/cpp_virtual_destructors.html)

Best,
Daniel

David Wilkinson wrote:
daniel@xxxxxx wrote:

Hi,
I spent a week on tracking down some memory leak which apparently comes
from the stl or the c++-Implementation itself. I tried Visual Studio
2002 and Visual C++ 2005 which both created the problem. Since I do not
have anything sophisticated as for example Bounds Checker, I used the
debug heap. Here is the code, (compile an run in debug mode in a
default "Windows Console Application" project):

-----------------------------------------------------------------------
-----------------------------------------------------------------------
#include <crtdbg.h>
#include <string>

using namespace std;

class Base
{
public:
virtual void test() =0;
};

class Final : public Base
{
public:
string str;
void test() { str ="0123456789012345";}
};

int main(int argc,char **argv)
{
_CrtMemState state;
_CrtMemCheckpoint(&state);

Base *t =new Final;
t->test();
delete t;

_CrtMemState state2, stateDiff;
_CrtMemCheckpoint(&state2);
_CrtMemDumpAllObjectsSince(&state);
_CrtMemDifference(&stateDiff, &state, &state2);
_CrtMemDumpStatistics(&stateDiff);
}

-----------------------------------------------------------------------
-----------------------------------------------------------------------
This results in the following debug output:
-----------------------------------------------------------------------
-----------------------------------------------------------------------

Dumping objects ->
{45} normal block at 0x00323E70, 32 bytes long.
Data: <0123456789012345> 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35
Object dump complete.
0 bytes in 0 Free Blocks.
32 bytes in 1 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 64 bytes.

-----------------------------------------------------------------------
-----------------------------------------------------------------------

Thus I have a 32 bytes leak per call. Two more observations:
1. When changing the code from
Base *t =new Final;
to
Final *t =new Final;
the problem is resolved - no leak anymore.
2. When the string "0123456789012345" is less than 16 bytes long, the
leak disappears and the longer it becomes, the larger the leak.

I would like to know if anyone can reproduce this problem and if there
is a known workaround. I already had a short look at the MSKB but did
not find anything at once.

Thanks in advance for any help,
Daniel


Daniel:

Classes used as base class should always have virtual destructor. You
just found out why.

In your case, when string is less than 16 characters, no memory is
allocated on the heap (short string optimization, I think it is called).

David Wilkinson

.



Relevant Pages

  • Re: CPaintDC Memory Leak
    ... You may want to debug the ~CPaintDC() destructor, ... the memory leak did not appear. ...
    (microsoft.public.windowsce.embedded.vc)
  • Re: Problem with resources in MFC extension DLL
    ... paths I'm storing in the string table. ... Key here is that in a destructor, especially a destructor called during program shutdown, ... particular, extension DLLs require the dynamic DLL chain be intact, and that can be ... You should avoid trying to use resources in a destructor, ...
    (microsoft.public.vc.mfc)
  • Re: constructor and destructor
    ... > me a desired output. ... > class string{ ... > In the destructor 7 ... an unnamed temp is created length 7 containng "Praveen". ...
    (comp.lang.cpp)
  • Re: CString over LPARM?
    ... Reaching out from the thread to theApp bothers me. ... Knowing theApp has an m_pDlg member ... There should be no real need to make a copy of the string; ... There is only one memory leak left. ...
    (microsoft.public.vc.mfc)
  • Re: Problem with resources in MFC extension DLL
    ... paths I'm storing in the string table. ... It seems that you are saying that the destructor is being called *from the main program* ... You should avoid trying to use resources in a destructor, ... My program uses some classes from an extension dll. ...
    (microsoft.public.vc.mfc)