Created
June 17, 2014 16:51
-
-
Save Gibgezr/c44afb0c7084624f1c3c to your computer and use it in GitHub Desktop.
How to locate memory leaks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //this code sets up memory leak detection | |
| #ifdef _DEBUG | |
| #define _CRTDBG_MAP_ALLOC | |
| #include <crtdbg.h> | |
| #define DEBUG_NEW new(_CLIENT_BLOCK, __FILE__, __LINE__) | |
| #define new DEBUG_NEW | |
| #endif | |
| //the line below turns on memory leak detection in debug mode | |
| _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); | |
| If we use the memory leak detection code in our debug builds, we sometimes get filename + line numbers for mem leaks, and sometimes we don't: | |
| Detected memory leaks! | |
| Dumping objects -> | |
| {64} normal block at 0x00BE2DD8, 12 bytes long. | |
| Data: < > C4 16 16 00 00 00 00 00 01 00 00 00 | |
| {59} normal block at 0x00BE2D48, 12 bytes long. | |
| Data: <| > 7C FC 15 00 00 00 00 00 01 00 00 00 | |
| {54} normal block at 0x00BE2EB0, 2048 bytes long. | |
| Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD | |
| {53} normal block at 0x00BE2E68, 12 bytes long. | |
| Data: <| > 7C 85 13 00 00 00 00 00 01 00 00 00 | |
| {47} normal block at 0x00BE2D00, 12 bytes long. | |
| Data: < > AC 83 13 00 00 00 00 00 01 00 00 00 | |
| {46} normal block at 0x00BE2CB8, 12 bytes long. | |
| Data: <t > 74 83 13 00 00 00 00 00 01 00 00 00 | |
| Object dump complete. | |
| Looking at the first entry, you will see: | |
| {64} normal block at 0x00BE2DD8, 12 bytes long. | |
| Data: < > C4 16 16 00 00 00 00 00 01 00 00 00 | |
| The “{64}” is the memory allocation occurrence. So, there were 63 memory allocations | |
| which already occurred. | |
| “0x00BE2DD8” is the memory address of the allocation. | |
| The “Data: < >” shows the first 12 bytes of data at that memory space – so if it’s a | |
| string data, then you would see text. | |
| “C4 16 16 00 00 00 00 00 01 00 00 00” is for those 12 bytes in hex. | |
| So, at the point that the leak dump was done above, we know that some stuff had memory allocations but was not unallocated… so what does this give us? The main key here is the memory allocation instance – like the {64} in the above example. You can set a breakpoint at that memory allocation – below are two methods for doing this: | |
| 1. Do it in code by adding a line setting a breakpoint at that allocation: | |
| _crtBreakAlloc = 64; // Break at the 64th memory allocation. | |
| Or | |
| _CrtSetBreakAlloc(64); // Break at the 64th memory allocation. | |
| 2. Do it in the Watch window: | |
| Run the app in debug and add “_crtBreakAlloc” under the Name column. | |
| In the Value column, enter the allocation instance – in the example above, its 64. | |
| Please note that the allocation instance seems to reset to -1, so you may need to reset it at times. | |
| When you run the code, you will be prompted to break – do so. You will see that you stopped at a line like the following in dbgheap.c: | |
| /* break into debugger at specific memory allocation */ | |
| if (_crtBreakAlloc != -1L && lRequest == _crtBreakAlloc) | |
| _CrtDbgBreak(); | |
| From here, step-out until you get back to your source file – you will end-up at the line at which the memory allocation was done – so you know what was leaking now. From here you just need to find out why it was not released. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment