Proper way to check for memory leaks in Visual C++ - c++

I've been trying to improve my own personal C++ skills lately, so I implemented an Array List as a learning exercise. After I got it working, I started checking for memory leaks, and became very confused by the output.
Source on GitHub (main.cpp, ArrayList.cpp, ArrayList.h)
I got a lot of information about how to start checking for leaks from this page
from Microsoft (hence the declarations at the top of the main file, the start of the main function, and the top of the ArrayList.cpp file.
Visual Studio is telling me this information:
Detected memory leaks!
Dumping objects ->
c:\users\cody\desktop\arraylist\arraylist\arraylist.cpp(48) : {4267} normal block at 0x007F9BC8, 3992 bytes long.
Data: < > 00 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
Object dump complete.
The program '[16620] ArrayList.exe' has exited with code -1073741510 (0xc000013a).
And the section of code in question
void AL::ShrinkToFit()
{
int* newArray = new int[currentIndexOfFirstOpen]; //Line 48, as mentioned in the mem leak output
for (int i = 0; i < currentIndexOfFirstOpen; i++)
{
newArray[i] = currentArray[i];
}
int* oldArray = currentArray;
currentArray = newArray;
delete[] oldArray;
currentMaxLoad = currentIndexOfFirstOpen;
}
So clearly I'm missing something. If you check the ArrayList.cpp file linked above, it (under different circumstances) tells me I have a leak anywhere in that file that I have "new int[some number]". The page from Microsoft says that I have to use the preprocessor to redefine new because it only works with the C runtime, but it makes no mention of delete (or delete[]). Is this memory actually being leaked? I have a matching delete[] for every new[], but I can't tell if it is a legitimate leak or if the leak detecting tools just don't understand delete. I tried replacing delete with free (I let the preprocessor redefine new as in the Microsoft article), and it made no change. If I am leaking, can someone point out where/why?

I tried to run your code with Visual Leak Detector (https://vld.codeplex.com/) and it appears you don't have a memory leak, but when exiting (with the close button) the command prompt the leak detector fails and detects a leak in the line you mentioned. Try deleting this line in the main.cpp
Sleep(1000000); //hold the prompt open
and put this instead
std::cin.get();
return 0;
Provide a keystroke at the end of the program and exit with code 0 to the operating system, this should solve your problem.

Related

Detecting memory leaks in MFC application

I'm writing an MFC app using Visual 2017 and when the application exits in debug mode, I get this:
Detected memory leaks! Dumping objects -> {74} normal block at
0x00000230E49A7000, 16 bytes long. Data: <0 0 > 30 00 97
E4 30 02 00 00 00 00 00 00 00 00 00 00 Object dump complete.
So, in order to know which function is causing the leak, I've added these lines in stdafx.h:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
And these lines in CWinApp::InitInstance():
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(74);
Though, it did not work. I suspect that the 74th memory allocation number has been made before my code is executed. Which method could I overload to be certain to be called first?
Step into your app to start debugging (that's step, not run, so you'll be stopped in the debugger before anything in your program has run), then set _crtBreakAlloc to the allocation you want to stop at (74). Then run and you should get a break on the 74th allocation. CRT Debug Heap Details has information on this variable.
This Microsoft support article also lists instructions for using _crtBreakAlloc in the debugger.
Writing this code
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
in top of each implementation (.CPP) file, can help you to detect the source of memory leaks.
See also: How to detect memory leaks in MFC.

Memory leak in Crypto++ RSAES class

I'm trying to learn how to use Crypto++ classes. My goal is to generate public and private keys for RSA encryption and then do basic encryption and decryption of a plaintext.
So I'm taking their example from here -- "RSA Encryption Scheme (OAEP and SHA) using Filters", slightly modified for readability:
This parts works OK:
CryptoPP::AutoSeededRandomPool rng;
//Generate Parameters
CryptoPP::InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, 3072);
//Create Keys
CryptoPP::RSA::PrivateKey privateKey(params);
CryptoPP::RSA::PublicKey publicKey(params);
std::string plain="Hello world!", cipher, recovered;
//Encryption
CryptoPP::RSAES_OAEP_SHA_Encryptor e(publicKey);
But then when I call this block:
CryptoPP::StringSink* pSS = new CryptoPP::StringSink( cipher );
CryptoPP::PK_EncryptorFilter* pEF = new CryptoPP::PK_EncryptorFilter( rng, e, pSS);
CryptoPP::StringSource ss1( plain, true, pEF);
It causes the memory leak(s). I get the following in the Visual Studio output window:
Detected memory leaks!
Dumping objects ->
{24781} normal block at 0x029BCFF8, 28 bytes long.
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A
{24780} normal block at 0x029BCFB0, 8 bytes long.
Data: < > F8 CF 9B 02 00 00 00 00
Object dump complete.
OK, so I did the most obvious thing and added these:
delete pEF;
delete pSS;
but it caused an unhandled exception, so I assumed that one of the destructors in Crypto++ classes took care of deleting some of those objects.
So the question is -- where is this leak coming from?
I tried stepping into StringSink, PK_EncryptorFilter and StringSource with a Visual Studio debugger to see what's going on, but the code is quite convoluted to figure it out right away.
Any idea how to fix those memory leaks?
It causes the memory leak(s). I get the following in the Visual Studio
output window:
Detected memory leaks!
Dumping objects ->
{24781} normal block at 0x029BCFF8, 28 bytes long.
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A
{24780} normal block at 0x029BCFB0, 8 bytes long.
Data: < > F8 CF 9B 02 00 00 00 00
Object dump complete.
The code you used looks a tad bit unusual, but I believe its well formed.
I believe what you are seeing is Microsoft's decades old bug typeinfo.name() memory leaks. Its been around since the VC 5.0 or VC 6.0 days.
CryptoPP::StringSink* pSS = new CryptoPP::StringSink( cipher );
CryptoPP::PK_EncryptorFilter* pEF = new CryptoPP::PK_EncryptorFilter( rng, e, pSS);
CryptoPP::StringSource ss1( plain, true, pEF);
Here's what a pipeline often looks like:
CryptoPP::StringSource ss( plain, true,
new CryptoPP::PK_EncryptorFilter( rng, e,
new CryptoPP::StringSink( cipher )));
Everything that follows the code above is a red herring. You went down a rabbit hole because Microsoft won't fix their bugs.
OK, so I did the most obvious thing and added these:
delete pEF;
delete pSS;
but it caused an unhandled exception
Yeah, that was not right. From the Readme.txt:
* Important Usage Notes *
If a constructor for A takes a pointer to an object B (except primitive types such as int and char), then A owns B and will delete B
at A's destruction. If a constructor for A takes a reference to an
object B, then the caller retains ownership of B and should not
destroy it until A no longer needs it.
Crypto++ is thread safe at the class level. This means you can use Crypto++ safely in a multithreaded application, but you must provide
synchronization when multiple threads access a common Crypto++ object.
pEF and pSS were pointers, and they were owned by someone else. They got deleted twice, which caused the exception.
Memory leak in Crypto++ RSAES class ...
If you run the cryptest.exe program, then you will see 60 or 80 leaks reported. I've tried to find a solution to that bug for about 10 or 15 years. Most recently was How to remediate Microsoft typeinfo.name() memory leaks? on Stack Overflow.
EDIT also see Windows Debug build memory leaks cleared on the user list and Commit 301437e693fe8bff. The library moved to static initialization from dynamic initialization to avoid problems on Microsoft platforms. The static initializer list is accessed with inti_seg on Windows; and constructor and init_priority attributes with GCC.
Its a "best effort" to use static initialization, if available. Otherwise, things fall back to dynamic initialization. Here, "static initialization" means getting the library into the CRT static initialization list that runs constructor functions and calls global object ctors (and not a vanilla C++ static object).

Why is my linked list "next" pointer dereferencing to the wrong memory (XCode, C++)

Can someone please help me figure out why the "next" pointer in my linked list is dereferencing to the wrong memory address in code on 32-bit platform, but works fine on 64-bit platform? My program is built as a universal binary on Xcode 7.3 and written in C++.
I've got a linked list, and dereferencing the "next" pointer in the debugger shows the correct memory, but dereferencing it in code reads the memory that is 4-bytes beyond where it should read. I will try to explain..
The objects on the list are 4144 bytes each, the last 4-bytes are a 32-bit pointer to the "next" item on the list. Looking at the "next" pointer in memory (0xBFFD63AC), we see that it is 4 zeros (NULL), this is correct. BUT notice that memory at 0xBFFD63B0 is a 0x01. This is the byte beyond the "next" pointer. When I ask the debugger to print the next variable, it prints the proper value (NULL):
(lldb) print l_pObject->Next
(Object__t *) $0 = 0x00000000
(lldb) memory read &(l_pObject->Next)
0xbffd63ac: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
However, if I execute the code that dereferences the "next" pointer, it actually reads the data from 0xBFFD63B0 instead of 0xBFFD63AC:
l_pObject = l_pObject->Next;
(lldb) print l_pObject
(Object_t *) $3 = 0x00000001
(lldb) memory read &(l_pObject)
0xbffd2504: 01 00 00 00 80 53 fd bf 00 00 00 00 6c 82 2e
I am positive it is reading the 0x01 from 0xBFFD63B0. The debugger seems to know that "next" indicates the memory at 0xBFFD63AC, but for some reason dereferencing "next" in code actually reads from 0xBFFD63B0, but I'm not sure how to figure out why. I've tried adding __attribute__((packed)) to the struct, but that made no difference. It's difficult to determine where things are going wrong because the debugger is telling me something different from what is really happening. Any tips on how to proceed from here would be very greatly appreciated!
EDITED TO ADD MORE INFO:
In the least there is a debugger error here! I ask the debugger to print the sizeof the struct and it gives me 4144, but in code I use the C funciton sizeof() and that gives me 4148! So there is definitely padding happening in the struct, but the debugger and apparently this section of code are blind to it. This is the root of my problem.
Debugger:
(lldb) print sizeof(*l_pObject)
(unsigned long) $0 = 4144
Code:
unsigned int iSizeOf = sizeof(*l_pObject); /* iSizeOf will equal 4148! */
Something funny is happening...
Without seeing the code it is impossible to tell. In general though, pointers tend to be 8-bytes wide on 64-bit systems and 4-bites wide on 32-bit systems. Obviously you observed that it's jumping 4 bytes beyond where it should be, which is a strong indicator. (0xBFFD63B0 - 0xBFFD63AC) == 4.
OK I found the problem, I should have realized it right away. The code that was crashing is in a library. Both the library and the calling application share definitions for variable types. Due to a missing preprocessor flag on the application side, one of those types was being allocated 4-bytes smaller on the application side than in the library code. So when the application created a linked list of objects and passed a reference to the library, each object on that list was 4-bytes smaller than the library was expecting them to be. What made it less obvious was the debugger was showing me addresses and offsets based on what was allocated in the application, so at first glance everything appeared to be sized correctly. I decided to not trust the debugger and wrote my own code to check addresses and offsets, and that's when it became obvious what was happening. So anyway, long story short, be sure your application and library allocate types to be the same size and then things will work much better. :)

How to ignore false positive memory leaks from _CrtDumpMemoryLeaks?

It seems whenever there are static objects, _CrtDumpMemoryLeaks returns a false positive claiming it is leaking memory. I know this is because they do not get destroyed until after the main() (or WinMain) function. But is there any way of avoiding this? I use VS2008.
I found that if you tell it to check memory automatically after the program terminates, it allows all the static objects to be accounted for. I was using log4cxx and boost which do a lot of allocations in static blocks, this fixed my "false positives"...
Add the following line, instead of invoking _CrtDumpMemoryLeaks, somewhere in the beginning of main():
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
For more details on usage and macros, refer to MSDN article:
http://msdn.microsoft.com/en-us/library/5at7yxcs(v=vs.71).aspx
Not a direct solution, but in general I've found it worthwhile to move as much allocation as possible out of static initialization time. It generally leads to headaches (initialization order, de-initialization order etc).
If that proves too difficult you can call _CrtMemCheckpoint (http://msdn.microsoft.com/en-us/library/h3z85t43%28VS.80%29.aspx) at the start of main(), and _CrtMemDumpAllObjectsSince
at the end.
1) You said:
It seems whenever there are static objects, _CrtDumpMemoryLeaks returns a false positive claiming it is leaking memory.
I don't think this is correct. EDIT: Static objects are not created on heap. END EDIT: _CrtDumpMemoryLeaks only covers crt heap memory. Therefore these objects are not supposed to return false positives.
However, it is another thing if static variables are objects which themselves hold some heap memory (if for example they dynamically create member objects with operator new()).
2) Consider using _CRTDBG_LEAK_CHECK_DF in order to activate memory leak check at the end of program execution (this is described here: http://msdn.microsoft.com/en-us/library/d41t22sb(VS.80).aspx). I suppose then memory leak check is done even after termination of static variables.
Old question, but I have an answer. I am able to split the report in false positives and real memory leaks. In my main function, I initialize the memory debugging and generate a real memory leak at the really beginning of my application (never delete pcDynamicHeapStart):
int main()
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
char* pcDynamicHeapStart = new char[ 17u ];
strcpy_s( pcDynamicHeapStart, 17u, "DynamicHeapStart" );
...
After my application is finished, the report contains
Detected memory leaks!
Dumping objects ->
{15554} normal block at 0x00000000009CB7C0, 80 bytes long.
Data: < > DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD
{14006} normal block at 0x00000000009CB360, 17 bytes long.
Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74
{13998} normal block at 0x00000000009BF4B0, 32 bytes long.
Data: < ^ > E0 5E 9B 00 00 00 00 00 F0 7F 9C 00 00 00 00 00
{13997} normal block at 0x00000000009CA4B0, 8 bytes long.
Data: < > 14 00 00 00 00 00 00 00
{13982} normal block at 0x00000000009CB7C0, 16 bytes long.
Data: < # > D0 DD D6 40 01 00 00 00 90 08 9C 00 00 00 00 00
...
Object dump complete.
Now look at line "Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74".
All reportet leaks below are false positives, all above are real leaks.
False positives don't mean there is no leak (it could be a static linked library which allocates heap at startup and never frees it), but you cannot eliminate the leak and that's no problem at all.
Since I invented this approach, I never had leaking applications any more.
I provide this here and hope this helps other developers to get stable applications.
Can you take a snapshot of the currently allocated objects every time you want a list? If so, you could remove the initially allocated objects from the list when you are looking for leaks that occur in operation. In the past, I have used this to find incremental leaks.
Another solution might be to sort the leaks and only consider duplicates for the same line of code. This should rule out static variable leaks.
Jacob
Ach. If you are sure that _CrtDumpMemoryLeaks() is lying, then you are probably correct. Most alleged memory leaks that I see are down to incorect calls to _CrtDumpMemoryLeaks(). I agree entirely with the following; _CrtDumpMemoryLeaks() dumps all open handles. But your program probably already has open handles, so be sure to call _CrtDumpMemoryLeaks() only when all handles have been released. See http://www.scottleckie.com/2010/08/_crtdumpmemoryleaks-and-related-fun/ for more info.
I can recommend Visual Leak Detector (it's free) rather than using the stuff built into VS. My problem was using _CrtDumpMemoryLeaks with an open source library that created 990 lines of output, all false positives so far as I can tell, as well as some things coming from boost. VLD ignored these and correctly reported some leaks I added for testing, including in a native DLL called from C#.

Visual Studio 2008 (C++) memory leak detection not showing file/method location - how to get that to work?

I am using the instructions found here to try to find memory leaks in a Win32 application. As described, I put the
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Lines at the top of a file (the cpp file that contains WINAPI _tWinMain) and then at the exit point of winmain I added
_CrtDumpMemoryLeaks();
Unfortunately I do not see the line numbers/locations for the leaks (but I do get a list of leaks).
I also tried putting
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG);
at the beginning of winmain - and again, no luck.
I find this odd because I usually have had no problems ever finding leaks or having them reported automatically.
This is a huge, old legacy app I am working on for a new employer. In the past I have worked from the standard VS wizard.
Any suggestions on how to get source lines/methods that are causing the leaks? (or at least the lines for the "new" calls?
EDIT:
I also tried visual leak detector - with no success.
Very strange.
EDIT
I tried using the redefinition of new as listed below, however I get errors when boost is compiled in.
Are you sure the code that's leaking is using the CRT debug allocation routines? That requires using malloc() or new (as opposed to LocalAlloc, GlobalAlloc, some custom block allocator, etc..) and that _DEBUG (I think) must be defined when the CRT headers were included.
In order to get source lines for leaks, you will need to define DEBUG_NEW everywhere the allocations occur. This is because in order to track them, each allocation must be replaced with a call that includes __FILE__ and __LINE__. The standard definition from the wizard looks something like:
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
This doesn't handle malloc, there's probably a similar incantation for that, if the code you're debugging uses malloc instead of new.
If you're using pre-compiled headers, you can just put this in the precompiled header file and it will affect all the source files in that project.
Given a list of leaks at the end of the run, something like:
Detected memory leaks!
Dumping objects ->
{12913} normal block at 0x000002BC648BB9D0, 82 bytes long.
Data: <h t t p : / / a > 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 61 00
{12912} normal block at 0x000002BC648B8030, 24 bytes long.
Data: <0 d ` > 30 CD 89 64 BC 02 00 00 D8 02 60 E5 F7 7F 00 00
...
It is easy to find where these memory blocks were allocated using _CrtSetBreakAlloc for example for stop when allocation with allocation number 12913 happens one has to put
...
_CrtSetBreakAlloc(12913);
...
somewhere in code before the allocation happens: beginning of the unit tests or main-function are some possible examples. Now, void* __CRTDECL operator new(size_t const size) will throw an exception when block with allocation number 12913 is allocated and from the call-stack in debugger it is easy to find where the allocation did happen.