4

I can't tell if there's something really obvious that I'm missing, but I'm writing a small game and I got some memory leaks using DrMemory. I couldn't figure out what was wrong exactly, so I wrote a simpler file that kinda modeled what my game was doing with memory.

class A{
public:
    A() { a = new int[10]; };
    ~A() { delete[] a; };
private:
    int* a;
};

int main()
{
    A a;

    return 0;
}

DrMemory is still telling me that I have a memory leak of two bytes, and I really cannot figure out what would be causing it. This is the error message that was generated

Error #1: LEAK 2 direct bytes 0x00da0c98-0x00da0c9a + 0 indirect bytes
# 0 replace_malloc                            [d:\drmemory_package\common\alloc_replace.c:2576]
# 1 msvcrt.dll!_strdup   
# 2 .text                                     [../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S:184]
# 3 __mingw_glob                              [../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S:184]
# 4 _setargv     
# 5 .text        
# 6 mainCRTStartup
# 7 ntdll.dll!RtlInitializeExceptionChain    +0x62     (0x77849802 <ntdll.dll+0x39802>)
# 8 ntdll.dll!RtlInitializeExceptionChain    +0x35     (0x778497d5 <ntdll.dll+0x397d5>)

How can I fix it? And can someone explain what the error is trying to say beyond the fact that there is a memory leak? Thanks!

Allen Yao
  • 61
  • 5
  • Looks like that's in the C++ runtime initialization code, not your program directly. If so, there's nothing you can do about it. – Shawn Dec 19 '18 at 07:39
  • 1
    Smells like a false positive with the CRT initialization. Quick thing to try. Update `main` to be declared as `main(int argc, char** argv)` – selbie Dec 19 '18 at 07:40
  • 5
    Likely not the answer (hence in a comment), but the class you present *is* vulnerable to memory issues: you should make it non-copyable and not-assignable. Otherwise `a` could be `delete[]`d more than once, which is undefined behaviour. Your best bet is to use `std::vector` rather than the array. – Bathsheba Dec 19 '18 at 07:51
  • @selbie I tried what you'd suggested, and it's still reporting the same error. Quick question, how does a false positive happen? I'm use to using valgrind in school and I never had this happen. Thanks again! – Allen Yao Dec 19 '18 at 07:52
  • Be aware of [C++ rule of five](https://en.cppreference.com/w/cpp/language/rule_of_three) – Basile Starynkevitch Dec 19 '18 at 07:57
  • It seems that mingw does not clean up its memory correctly (leak in __mingw_glob when calling to _glob_strdup function). – tunglt Dec 19 '18 at 07:59

1 Answers1

2

There are no memory leaks, but possible a false positive.
Here is what I get when I run Dr. Memory:

Dr. Memory version 1.11.0 build 2 built on Aug 29 2016 02:42:07
Dr. Memory results for pid 10412: "memoryleakcheck.exe"
Application cmdline: "C:\Users\user\dev\cpptests\memoryleakcheck\Debug\memoryleakcheck.exe"
Recorded 115 suppression(s) from default C:\Temp\DrMemory-Windows-1.11.0-2\bin\suppress-default.txt

Error #1: INVALID HEAP ARGUMENT to free 0x01d000f8
# 0 replace_free                      [d:\drmemory_package\common\alloc_replace.c:2706]
# 1 memoryleakcheck.exe!?            +0x0      (0x0028231e <memoryleakcheck.exe+0x1231e>)
# 2 memoryleakcheck.exe!?            +0x0      (0x00281aec <memoryleakcheck.exe+0x11aec>)
# 3 memoryleakcheck.exe!?            +0x0      (0x00281933 <memoryleakcheck.exe+0x11933>)
# 4 memoryleakcheck.exe!?            +0x0      (0x00281a46 <memoryleakcheck.exe+0x11a46>)
# 5 memoryleakcheck.exe!?            +0x0      (0x0028222e <memoryleakcheck.exe+0x1222e>)
# 6 memoryleakcheck.exe!?            +0x0      (0x00282097 <memoryleakcheck.exe+0x12097>)
# 7 memoryleakcheck.exe!?            +0x0      (0x00281f2d <memoryleakcheck.exe+0x11f2d>)
# 8 memoryleakcheck.exe!?            +0x0      (0x002822a8 <memoryleakcheck.exe+0x122a8>)
# 9 KERNEL32.dll!BaseThreadInitThunk +0x23     (0x76c762c4 <KERNEL32.dll+0x162c4>)
Note: @0:00:00.193 in thread 13020
Note: refers to -1 byte(s) before next malloc
Note: next higher malloc: 0x01d000f8-0x01d00120
Note: refers to -40 byte(s) beyond last valid byte in prior malloc
Note: prev lower malloc:  0x01d000f8-0x01d00120

Error #2: LEAK 40 direct bytes 0x01d000f8-0x01d00120 + 0 indirect bytes
# 0 replace_malloc                    [d:\drmemory_package\common\alloc_replace.c:2576]
# 1 memoryleakcheck.exe!?            +0x0      (0x002822bd <memoryleakcheck.exe+0x122bd>)
# 2 memoryleakcheck.exe!?            +0x0      (0x00281acc <memoryleakcheck.exe+0x11acc>)
# 3 memoryleakcheck.exe!?            +0x0      (0x00281884 <memoryleakcheck.exe+0x11884>)
# 4 memoryleakcheck.exe!?            +0x0      (0x00281a34 <memoryleakcheck.exe+0x11a34>)
# 5 memoryleakcheck.exe!?            +0x0      (0x0028222e <memoryleakcheck.exe+0x1222e>)
# 6 memoryleakcheck.exe!?            +0x0      (0x00282097 <memoryleakcheck.exe+0x12097>)
# 7 memoryleakcheck.exe!?            +0x0      (0x00281f2d <memoryleakcheck.exe+0x11f2d>)
# 8 memoryleakcheck.exe!?            +0x0      (0x002822a8 <memoryleakcheck.exe+0x122a8>)
# 9 KERNEL32.dll!BaseThreadInitThunk +0x23     (0x76c762c4 <KERNEL32.dll+0x162c4>)

===========================================================================
FINAL SUMMARY:

DUPLICATE ERROR COUNTS:

SUPPRESSIONS USED:

ERRORS FOUND:
      0 unique,     0 total unaddressable access(es)
      0 unique,     0 total uninitialized access(es)
      1 unique,     1 total invalid heap argument(s)
      0 unique,     0 total GDI usage error(s)
      0 unique,     0 total handle leak(s)
      0 unique,     0 total warning(s)
      1 unique,     1 total,     40 byte(s) of leak(s)
      0 unique,     0 total,      0 byte(s) of possible leak(s)
ERRORS IGNORED:
      6 potential error(s) (suspected false positives)
         (details: C:\Temp\DrMemory-Windows-1.11.0-2\drmemory\logs\DrMemory-memoryleakcheck.exe.10412.000\potential_errors.txt)
     17 unique,    29 total,   6711 byte(s) of still-reachable allocation(s)
         (re-run with "-show_reachable" for details)
Details: C:\Temp\DrMemory-Windows-1.11.0-2\drmemory\logs\DrMemory-memoryleakcheck.exe.10412.000\results.txt

I compiled with the default settings when I create a new project

/JMC /permissive- /GS /analyze- /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"Debug\vc141.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /FC /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\memoryleakcheck.pch" /diagnostics:classic 

and linker:

/OUT:"C:\Users\user\dev\cpptests\memoryleakcheck\Debug\memoryleakcheck.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\user\dev\cpptests\memoryleakcheck\Debug\memoryleakcheck.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FASTLINK /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\user\dev\cpptests\memoryleakcheck\Debug\memoryleakcheck.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\memoryleakcheck.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 
Damian
  • 4,395
  • 4
  • 39
  • 67
  • 1
    Okay thanks! Just curious, is this a problem with DrMemory? If so, is there another tool that I should use for detecting memory leaks? – Allen Yao Dec 19 '18 at 08:31
  • [Valgrind](http://valgrind.org/docs/manual/quick-start.html) is quite precise and extensive and does the job pretty well @AllenYao – M.K Dec 19 '18 at 08:37
  • I believe most memory detection tools issues false positives. Sometimes you might allocate memory for global variables on the stack (not the heap with new) and when the program exits these are remaining so the tools things there is a memory leak. I am sure there are other scenarios. Please mark my answer as correct.. thanks! – Damian Dec 19 '18 at 08:38
  • 2
    Valgrind is a great debugger. You can also use Deleaker. This debugger is looking for the main types of leaks, GDI and handles. These types of leaks are rare, but sometimes cause serious problems. – z0r1fan Dec 21 '18 at 18:54
  • If you don't want to instrument the code, and want to avoid false leaks associated with process exit, try https://github.com/vmware/chap – Tim Boddy Jan 30 '19 at 17:41