tags:

views:

233

answers:

3

Both code examples compile and run without problems. Using the second variant results in a memory leak. Any ideas why? Thanks in advance for any help.

Variant 1:

typedef boost::shared_ptr<ParameterTabelle> SpParameterTabelle;

struct ParTabSpalteData
{
      ParTabSpalteData(const SpParameterTabelle& tabelle, const string& id)
            :Tabelle(tabelle), Id(id)
      {

      }

      const SpParameterTabelle& Tabelle;
      string Id;
};

Variant 2:

struct ParTabSpalteData
{
      ParTabSpalteData(const SpParameterTabelle& tabelle, const string& id)
            :Id(id)
      {
            // causes memory leak
            Tabelle2 = tabelle;
      }

      SpParameterTabelle Tabelle2;
      string Id;
};
+2  A: 

Have you checked, that you do not have cyclic shared pointer references?

For example:

class A {
  public: shared_ptr<A> x;
}

shared_ptr<A> a1(new A());
shared_ptr<A> a2(new A());
a1->x = a2;
a2->x = a1;

Here a1 and a2 will never be released, because they have pointers to each other which keeps them alive.

So in your case check if SpParameterTabelle has a reference on ParTabSpalteData or if there is another possibility to get a cyclic reference.

Danvil
I was thinking that it might be such an issue. But I think example 1 should exhibit the same behaviour no ? or will it not because it is a reference rather than a shared_ptr itself ?
Hassan Syed
nabulke
Danvil
@nabulke Perhaps you should try to recreate a minimal instance of the problem so we can compile it ?
Hassan Syed
Rule of thumb I guess, taking a reference or pointer of a smart pointer is subverting the purpose of said smart pointer
Hassan Syed
A: 

Note that passing a smart pointer as const SpParameterTabelle& tabelle do not forbid you to change the pointee object.

Have you tried passing directly the smart pointer, as

struct ParTabSpalteData
{
      ParTabSpalteData(SpParameterTabelle tabelle, const string& id)
            :Tabelle2(tabelle), Id(id)
      {
      }

      SpParameterTabelle Tabelle2;
      string Id;
};
Vicente Botet Escriba
A: 

Output something in the destructor of ParameterTabelle (trace/fileout), or set a breakpoint there. Does it really not get called twice?

I recently upgraded a VS2005 project to VS2010 and suddenly VS2010 reported memory leaks in boost::lexical_cast. And not in all of them, just in one single module on a single line - there were even other lexical_cast of the same type/other types all around in that file.

Even local memory state tests reported this as memory leak (code for debug mode only):

void run_stream_tests(std::ofstream& out)
{
#ifdef _DEBUG
  CMemoryState preState;
  preState.Checkpoint();
#endif
  {
    ...your code...
  }
#ifdef _DEBUG
  CMemoryState postState;
  postState.Checkpoint();
  CMemoryState diffState;
  if( diffState.Difference( preState, postState ) )
  {
    TRACE("Memory leaked!\n");
    preState.DumpAllObjectsSince();
  }
#endif
}

So, this could also be a VS2010/VS2008 problem.

ToastedSoul
Thanks for your input. Considerung this I will use Boundschecker or Purify to get a second opinion concerning the memory leaks.
nabulke