Where is the memory leak?

Feb 23, 2009 at 7:05pm
Hi all,

I just learned how to look for memory leaks from this forum, and found my code has one. I eliminated all code not relevant to the memory leak. The code compiles and links (VC express), you can just create a console application to test it!

Set two break points at lines 12 of test.cpp: where is the memory leak?

Simplifying the code any further yields no memory leak report.

[Edit simplified from first post]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//file test.h
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h> 
template <class Object>
class ListObjectPointers
{
public:
  int size;
  Object** TheObjects;
  ListObjectPointers();
  ~ListObjectPointers();
};
template <class Object>
ListObjectPointers<Object>::ListObjectPointers()
{
  _CrtDumpMemoryLeaks();
  this->size=0;
  this->TheObjects=0;
};
template <class Object>
ListObjectPointers<Object>::~ListObjectPointers()
{
  delete [] TheObjects;
}
class PolynomialPointers: public ListObjectPointers<int>
{
public:
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
//file test.cpp
#include "stdafx.h"
#include "test.h"
#include <iostream>
#include <limits>
int _tmain(int argc, _TCHAR* argv[])
{
  PolynomialPointers* ThePolys;
  ThePolys = new PolynomialPointers;
  std::cout << "Press ENTER to continue...";
  std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
  delete ThePolys;
  return 0;
}


Thanks a lot for helping me figure this one! Here is what I read on memory leaks:

http://www.cplusplus.com/forum/general/2335/
Last edited on Feb 23, 2009 at 7:22pm
Feb 23, 2009 at 7:52pm
closed account (z05DSL3A)
I think you are seeing a false report here, _CrtDumpMemoryLeaks(); should be called at the end of main.
Feb 23, 2009 at 8:13pm
Is that possibly because an initialization list was not used to zero the pointer? Maybe try that...(I'm not familiar with _CrtDumpMemoryLeaks)
Feb 23, 2009 at 8:56pm
closed account (z05DSL3A)
This would be how I would setup the test app
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "stdafx.h"
#include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h> 



void onExit( void )
{
    _CrtDumpMemoryLeaks();
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Register the function that will be called
    // when the program exits
    atexit(onExit);
    
    // Code to test....
    int* pInt = new int(2);

    // now for a memory leak
    pInt = new int(3);

    delete pInt;

    return 0;
}


Detected memory leaks!
Dumping objects ->
{162} normal block at 0x00299690, 4 bytes long.
Data: < > 02 00 00 00
Object dump complete.
The program '[5300] RandomTest.exe: Native' has exited with code 0 (0x0).
Debug output
Last edited on Feb 23, 2009 at 8:57pm
Feb 23, 2009 at 9:42pm
Got it! Thanks, it unfortunately means _CrtDumpMemoryLeaks() has less of a use for me... A question naturally comes.

I have a lot of global objects in two different files. So, I need to call _CrtDumpMemoryLeaks() at the destructor of the class of the first global object created (since it will be the last one destroyed, right?). Now which of the two files takes priority?
Feb 23, 2009 at 11:29pm
closed account (z05DSL3A)
The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution. When you program finishes the net result of allocated and deallocated memory should be zero. If it is not _CrtDumpMemoryLeaks will just list the un-deallocated data. You can sometimes work out what has not been deallocated from the data, but from the sound of your posts this will likely be just lots of numbers.

The thing you will need to do is run your code with a small data-set and see if that produces a memory leak, increasing the size until it does. Then look at your code to see what is happening with that size data-set, the need to grow your list...

... or just take a good look at the places you call new and delete
Feb 26, 2009 at 2:31pm
Grey Wolf, I ran into a problem using _CrtDumpMemoryLeaks that was detecting false memory leaks. For example, try this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stdafx.h"
#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h>
#include <crtdbg.h>

#include <iostream>
#include <string>
using namespace std;

const string test("Test const string");

void onExit( void )
{
    _CrtDumpMemoryLeaks();
}

int _tmain(int argc, _TCHAR* argv[])
{

	atexit(onExit);
	cout << test;

	return 0;
}


And you get this result:
Detected memory leaks!
Dumping objects ->
{158} normal block at 0x003498F0, 32 bytes long.
Data: <Test const strin> 54 65 73 74 20 63 6F 6E 73 74 20 73 74 72 69 6E
Object dump complete.


Apparently with that code _CrtDumpMemoryLeaks() is getting called before all object deallocation has been completed by the application. If you instead put this code

 
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


at the start of main(), you don't have to explicitely call any function at the end of main and you won't see these false memory leaks.
Feb 26, 2009 at 2:33pm
[Edit:] besides the below measures I took for a memory leak I found where my actual memory leak. I will post a topic about it in the lounge since I feel like shooting the breeze about c++ :)

In fact I now adopted the "Garbage collector" trick in order not to put too much thought into it.

in code form:
1
2
3
4
5
6
7
8
9
10
//file: polyhedra.h
class CombinatorialChamber
{
public:
  CombinatorialChamber();
};
class CombinatorialChamberPointers:public ListObjectPointers<CombinatorialChamber>
{
public:
};


1
2
3
4
5
6
7
8
9
10
11
//file: polyhedra.cpp
CombinatorialChamberPointers GlobalCollectorChambers;
CombinatorialChamber::CombinatorialChamber()
{
  GlobalCollectorChambers.AddObjectpointer(this);
}

void exitDLL()
{
  GlobalCollectorChambers.KillAllElements();
}


The non-defined functions/classes with the long names above do what their name says they do :)
Last edited on Feb 26, 2009 at 2:33pm
Topic archived. No new replies allowed.