How to detect memory leaks poperly ?

closed account (GbRGwA7f)
I am trying to understand if my program is causing memory leaks. I do not know what to do. Any idea ?

main.cpp
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
30
31
32
33
34
35
36
37
38
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include "systemclass.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
	SystemClass* System;
	bool result;



	// Create the system object.
	System = new SystemClass;
	if (!System)
	{
		return 0;
	}
	// Initialize and run the system object.
	result = System->Initialize();
	if (result)
	{
		System->Run();
	}

	// Shutdown and release the system object.
	System->Shutdown();
	delete System;
	System = 0;

	_CrtDumpMemoryLeaks();

	return 0;

}


OUTPUT WHEN RUN:
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
Detected memory leaks!
Dumping objects ->
{213} normal block at 0x007BEA50, 96 bytes long.
 Data: <7 0 F r a m e s > 37 00 30 00 46 00 72 00 61 00 6D 00 65 00 73 00 
{167} normal block at 0x00741E68, 1 bytes long.
 Data: < > CD 
{166} normal block at 0x00741E08, 1 bytes long.
 Data: < > CD 
{156} normal block at 0x0074C0A8, 8 bytes long.
 Data: < u      > F0 75 E4 00 00 00 00 00 
{155} normal block at 0x0074C700, 8 bytes long.
 Data: < u      > B4 75 E4 00 00 00 00 00 
Object dump complete.
The thread 0x69d4 has exited with code 0 (0x0).
The thread 0x5598 has exited with code 0 (0x0).
The thread 0x5d64 has exited with code 0 (0x0).
The thread 0x2ff8 has exited with code 0 (0x0).
The thread 0x3550 has exited with code 0 (0x0).
The thread 0xa04 has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
{167} normal block at 0x00741E68, 1 bytes long.
 Data: < > CD 
{166} normal block at 0x00741E08, 1 bytes long.
 Data: < > CD 
Object dump complete.
The program '[1604] gomiDX.exe' has exited with code 0 (0x0).



UPDATES:
FOR: Data: <7 0 F r a m e s > 37 00 30 00 46 00 72 00 61 00 6D 00 65 00 73 00 I defined it from class header and assigned L"" in classNAME::classNAME() that did not appear again as leak.



UPDATE:
systemclass.h file:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
////////////////////////////////////////////////////////////////////////////////
// Filename: systemclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _SYSTEMCLASS_H_
#define _SYSTEMCLASS_H_
///////////////////////////////
// PRE-PROCESSING DIRECTIVES //
///////////////////////////////
#define WIN32_LEAN_AND_MEAN
//////////////
// INCLUDES //
//////////////

#include <windows.h>
///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "inputclass.h"
#include "graphicsclass.h"
#include <stdio.h>
#include <string> 

////////////////////////////////////////////////////////////////////////////////
// Class name: SystemClass
////////////////////////////////////////////////////////////////////////////////
class SystemClass
{
public:
	SystemClass();
	SystemClass(const SystemClass&);
	~SystemClass();
	bool Initialize();
	void Shutdown();
	void Run();
	GraphicsClass* m_Graphics;
	bool IS_CAPS_LOCK_ON;
	static bool WINDOW_RESIZED;
	
	LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
	LRESULT CALLBACK MessageHandler_OWNER(HWND, UINT, WPARAM, LPARAM);
private:
	bool Frame();
	void InitializeWindows(int&, int&);
	void ShutdownWindows();
private:
	LPCWSTR m_applicationNameOwner;
	LPCWSTR m_applicationName;
	HINSTANCE m_hinstance;
	HWND m_hwnd;

	HWND m_hwndOWNER;
	HINSTANCE m_hinstanceOWNER;

	InputClass* m_Input;

};


/////////////////////////
// FUNCTION PROTOTYPES //
/////////////////////////
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


/////////////
// GLOBALS //
/////////////
static SystemClass* ApplicationHandle = 0;


#endif 

Last edited on
What's systemclass.h have?

I'd bet the class you've described in there has a faulty destructor.
new never returns a null pointer.

closed account (GbRGwA7f)
Tomorrow I will add more details. I suspect I defined some 1 to 8 byte data type out of class constructor. So that cant be DX11 resource. For now just correct if I am mistaken at reporting part of Visual Studio's _CrtDumpMemoryLeaks(); tool.
Last edited on
> {166} normal block at 0x00741E08, 1 bytes long.
If 166 is a consistent number between runs, then you could use this.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetbreakalloc?view=vs-2019

If you're running in the debugger at the time, it will stop on that allocation.
Backtrack up the stack to find out what pointer gets allocated, then you can figure out how to free it.
closed account (GbRGwA7f)
Very interesting,

For 1 bytes long data I found them.

In my armNetwork.cpp file I did something very wrong. I don't even know why I did this kind of mistake. I put "!" for ARM_svr(ARMNET_Server class) and ARM_clt (ARMNET_Client class) in IF condition so they were never destroyed.

Memory Leaked Part of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

...
void ARMNETWORK::Shutdown()
{
	if (!ARM_svr) // -> HERE
	{
		ARM_svr->Shutdown();
		delete ARM_svr;
		ARM_svr = 0;
	}

	if (!ARM_clt) // -> HERE
	{
		ARM_clt->Shutdown();
		delete ARM_clt;
		ARM_clt = 0;
	}
};

...


8 byte is still there.
closed account (GbRGwA7f)
8 byte looks like:

I tried removing everything from code. So I do not install System inside WinMain.

I did this:
1
2
3
4
5
6
7
8
9
10
11
#include "systemclass.h"
#include "CRT_helper.h" //CRT headers

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PSTR pScmdline, _In_  int iCmdshow)
{
//NO CODE HERE
//I removed System class which creates new classes from other cpp files.
//NO CODE HERE
_CrtDumpMemoryLeaks();
return 0;
};


I still get this 8 byte leak. What can be the reason ? I also added systemclass.h file to the end of post
unlikely but cut systemclass.h include too.
if that does not do it, make the same code in a console program, preferably using 2-3 compilers. If they all say the same thing, then your dump leaks function needs to be debugged?

memory leak detectors are notorious for false positives. They are designed to look for things and they find them, whether right or wrong. Its gotten better (the early ones were barely usable, you ran them and then human double checked everything it found which could take forever on a big project). If I ran a program for several hours and had only 8 bytes unaccounted for, I would be satisfied unless it runs on an always up machine that does not have an operating system or one that cleans up. The memory leaks that are big trouble are the ones that drop bytes every time through a loop or loop like cycle (thread, etc). Even if its a little per go, it adds up over time, those weird 'it crashes like clockwork every 2 hours' type bugs. The other big ones are large amounts lost even if only once or twice. Hopefully if you make something that big, you pay extra attention to it.
closed account (GbRGwA7f)
@jonnin
unlikely but cut systemclass.h include too.
I removed it and replaced by <Windows.h> and tried to run empty WinMain and yes that did not cause any leak. The problem is when I include "systemclass.h" that leaves 8 bytes I did not get why.
Last edited on
systemclass.h includes also "inputclass.h" and "graphicsclass.h" which may have the memory leak. Can't know for sure without seeing it. You could have a static member that's not being deleted.
still, getting the file with the issue is a start
the only thing it should do in that header if you don't use the class anywhere is the static variables.
I don't know the rules on that, whether your memory leak tool knows to let the statics be destroyed at program end before it checks, or if it loses track of those.

what happens if you make similar static variables in a dummy.h file? Are the static vars messing you up? If they are, I would call that a false positive and ignore it.
Last edited on
closed account (GbRGwA7f)
Yes adding a static variable in my class caused same problem about 4 bytes.

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// MemlLeakDetect.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <string>
#include <iostream>

#include "windows.h"
#define _CRTDBG_MAP_ALLOC //to get more details
#include <stdlib.h>  
#include <crtdbg.h>   //for malloc and free

class testClass {
public:
    int p1;
    testClass() {
        p1 = 512;
    };

};

static testClass* ApplicationHandle = 0;

int main()
{
    _CrtMemState sOld;
    _CrtMemState sNew;
    _CrtMemState sDiff;
    _CrtMemCheckpoint(&sOld); //take a snapchot
    testClass* testcls = new testClass;
    ApplicationHandle = testcls;
    // OK
    int* p = new int;
    delete p;
    
    // Memory leak
    std::string* q = new std::string("tasdasfdsfgdsgsdgdsgdfgfdhbgfbhgfbhfg");
    // no delete
    std::cout << q;
    delete q;
    

    _CrtMemCheckpoint(&sNew); //take a snapchot 
    if (_CrtMemDifference(&sDiff, &sOld, &sNew)) // if there is a difference
    {
        OutputDebugString(L"-----------_CrtMemDumpStatistics ---------");
        _CrtMemDumpStatistics(&sDiff);
        OutputDebugString(L"-----------_CrtMemDumpAllObjectsSince ---------");
        _CrtMemDumpAllObjectsSince(&sOld);
        OutputDebugString(L"-----------_CrtDumpMemoryLeaks ---------");
        _CrtDumpMemoryLeaks();
    }

    delete testcls; testcls = 0;
    ApplicationHandle = NULL;

    return 0;

}


OUT:
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
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Users\gomi\source\repos\MemlLeakDetect\Debug\MemlLeakDetect.exe'. Symbols loaded.
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp140d.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\vcruntime140d.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'. 
The thread 0x6e90 has exited with code 0 (0x0).
4 bytes in 1 Normal Blocks.
60 bytes in 7 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 535 bytes.
Total allocations: 11544 bytes.
-----------_CrtMemDumpAllObjectsSince ---------Dumping objects ->
{153} normal block at 0x00CC9C68, 4 bytes long.
 Data: <    > 00 02 00 00 
Object dump complete.
-----------_CrtDumpMemoryLeaks ---------Detected memory leaks!
Dumping objects ->
{153} normal block at 0x00CC9C68, 4 bytes long.
 Data: <    > 00 02 00 00 
Object dump complete.
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel.appcore.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcryptprimitives.dll'. 
'MemlLeakDetect.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. 
The thread 0x5084 has exited with code 0 (0x0).
The thread 0x48bc has exited with code 0 (0x0).
The thread 0x5b34 has exited with code 0 (0x0).
The program '[14916] MemlLeakDetect.exe' has exited with code 0 (0x0).
Last edited on
ok. you can try to fix that if you wrote the leak detector yourself, or you can ignore it, secure in the knowledge that its a false alarm and that the memory will be recovered as the program goes through its destruction and deallocation process.
Topic archived. No new replies allowed.