I have a vector as below.
std::vector<std::string> exportNameList;
I am adding elements to this by using push_back method. But I am getting a debug assertion as "
"Windows has triggered a breakpoint in AxCent.exe.This may be due to a corruption of the heap, which indicates a bug in AxCent.exe or any of the DLLs it has loaded.
This happens when it calls the destructor of the class. When I refer to the call stack I was directed to the following code block in the vector class.
~vector()
{ // destroy the object
_Tidy();
}
What I noticed is there is an error when deleting the vector. Am I correct? How do I fix this? I have referred to many examples, but did not manage to work this out yet. I am quite new to C++.
Thanks a lot.
You are presumably corrupting the memory used by the vector somewhere else.
The bug you encounter may not be directly related to your vector.
If the memory (heap) is corrupted before the destructor of your vector is called, then the heap manager may only detect the corruption at this time (freeing the structure dynamically allocated by the vector or the dynamically allocated strings inside).
In my opinion, the best way to handle these kinds of bugs on the Windows platform is to activate the Full Page Heap for your program.
You can do this in 2 ways :
either using gflags contained in the 'Debugging Tools for Windows'. Run it as administrator, go to the 'Image File' tab, enter the name of your EXE in the Image field (AxCent.exe), press TAB and check 'Enable page heap' and press 'Apply'
or use Application Verifier. Select your executable through the File/App application menu make sur the check 'Basics/Heap' is checked and click save.
This setting will be applied whenever this application is launched.
Then run your application under a debugger (WindDbg or Visual Studio). If the memory is corrupted before your vector deletion, the debugger should break at this point.
When you are finished tracking the bug, don't forget to turn Full Page Heap off.
Related
Currently I have a solution but I am not sure if it's alright in every scenario. Can I check if there is any memory leaks in the program with this solution? If anyone can offer a better solution please do not hesitate to share the answer. Thanks!
My example code here:
int *array = new int[5];
delete[] array; //so no memory leaks
//Memory leak check.
if (_CrtDumpMemoryLeaks()) {
std::cout << "Memory leaks!\n";
}
else {
std::cout << "No leaks\n";
}
cin.get();
return 0;
I found an other solution - Can someone agree with it? (source: https://learn.microsoft.com/en-us/visualstudio/profiling/memory-usage?view=vs-2017 )
1st step - create 3 breakpoints. !!! The last breakpoint should have put after the return - not in line!
2nd step - Start debugging and creating snapshots. (Diagnostic Tool)
3rd step - Click on the second snapshot and see 3 variables allocated dynamically in the heap.
4th step - Click on the third snapshot that we made - so we took it after releasing memory of the 'a' pointer with: delete a; That's why the size here is only 8 bytes. (12 bytes - 4 bytes that we have just released)
In your case, the best suited thing would be as you used in the first place, the CRT library and indeed the use of _CrtDumpMemoryLeaks(); as Microsoft documentation says:
The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution.
Concerning your other doubt:
but I am not sure if it's alright in every scenario
Per the microsoft documentation, it should log any memory leak occuring in your whole program even if it is in a class or anywhere where you might think as it:
Dumps all the memory blocks in the debug heap when a memory leak has occurred
Also don't forget to #define the _DEBUG flag as mentionned here:
When _DEBUG is not defined, calls to _CrtDumpMemoryLeaks are removed during preprocessing.
but nevertheless if you're making software you should use STL and use smart pointers.
Also you might have another way of checking a memory leak for a certain resource at a time, I use the memory tab provided by visual studio when debugging which is located in debug > windows > memory > memory1 (Note: you'll have to be in debug mode to see the setting) then in the search bar you can type array so you go where your pointed to memory lives, and then you could just step into your program and see if the memory is nulled out or not.
Note:
This is more if you want to visually monitor one resource at a time and not if you want a whole dump of each possibly leaked resources.
I am calling into a statically linked .dll, and I see this error:
I wrote both the .dll and the calling code. This error should not be occurring. I am wondering if anyone else has encountered it before? The .dll only contains about 10 lines of code, its just a test .dll to see how dlls work in general. It blows up when I pass a std::string back out of the .dll.
I am using Visual Studio 2012 and C++.
What I will try next
From Debug assertion... _pFirstBlock == pHead:
This problem can occur if one uses the single-threading libraries in a
multithreaded module.
Tomorrow, I'll try recompiling the Boost static libraries in multi-threaded mode (my .dll is set to multi-threaded static mode).
What I will try next
See Using strings in an object exported from a DLL causes runtime error:
You need to do one of two things
Make both the DLL and the client that use it both link to the DLL version of the CRT (e.g. not statically).
OR You need to make sure you don't pass dynamically allocated memory (such as is contained in string objects) across DLL boundaries.
In other words, don't have DLL-exported functions that return string
objects.
Joe
This seems to match whats going on, it blows up at the precise point where I pass a string back across a .dll boundary. The problem only occurs when everything is linked in static mode. Now that's fixable.
See Passing reference to STL vector over dll boundary.
What I will try next
See Unable to pass std::wstring across DLL.
Solution
I have a nice solution, see the answer below.
In this case, the problem is that I was passing a std::string back across a .dll boundary.
Runtime Library config
If the MSVC Runtime library is set to Multi-threaded Debug DLL (/MDd), then this is no problem (it works fine).
If the MSVC Runtime library is set to Multi-threaded Debug (/MTd), then it will throw this error, which can be fixed with the following instructions.
Memory allocated in Memory Manager A and freed in Memory Manager B ...
The problem is that memory is allocated on the .dll side, then that same memory is freed on the application side. This means that memory manager A is allocating memory, and memory manager B is releasing that same memory, which generates errors.
The solution is to make sure that all memory passed back is not allocated in the DLL. In other words, the memory is always allocated on the application side, and freed on the application side.
Of course, the DLL can allocate/free memory internally - but it can't allocate memory that is later freed by the application.
Examples
This will not work:
// Memory is allocated on the .dll side, and freed on the app side, which throws error.
DLL std::string GetString();
This will work:
// Memory is allocated/freed on the application side, and never allocated in the .dll.
DLL int GetString(std::string& text);
However, this is not quite enough.
On the application side, the string has to be pre-allocated:
std::string text("");
text.reserve(1024); // Reserves 1024 bytes in the string "text".
On the .dll side, the text must be copied into the original buffer (rather than overwritten with memory that is allocated on the .dll side):
text.assign("hello");
Sometimes, C++ will insist on allocating memory anyway. Double check that the pre-allocation is still the same as it was:
if (text.capacity < 1024)
{
cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}
Another way that works is to use std::shared_ptr<std::string>, so even though memory is allocated in the .dll, it is released by the .dll (rather than the application side).
Yet another way is to accept a char * and a length which indicates the amount of pre-allocated memory. If the text that we want to pass back is longer than the length of pre-allocated memory, return an error.
This is what assert() looks like when its expression argument evaluates to false. This assert exists in the Debug build of the C runtime library, designed to check for allocation problems. The free() function in your case. The Debug build add extra checks to make sure you are writing your code correctly. And tell you when it detects a problem. Like calling free() on an allocation that was already freed, the simple case. Or calling free() passing the wrong pointer value, the trickier case. Or calling free() when the heap was corrupted by earlier code, the much harder case.
This is only as far as they can take it, they don't actually know why your code got it wrong. There is not any way they can put a Big Red arrow on the code that corrupted the heap for example. The easy case is covered by the Debug + Windows + Call Stack debugger window, it takes you to the code in your program that called free(). Or std::operator delete for a C++ program. The harder case is very, very hard indeed, heap corruption is often a Heisenbug. Getting the assert to be repeatable so you can set a data breakpoint on the reported address is the core strategy. Crossing fingers for the easy case, good luck with it!
After edit: yes, having cross-module problems with a C++ class like std::string is certainly one of the problems it can catch. Not a Heisenbug, good kind of problem to have. Two basic issues with that:
The modules might each have their own copy of the CRT, objects allocated by one copy of the CRT cannot be released by another copy of the CRT. They each have their own heap they allocate from. A problem that got addressed in VS2012, the CRT now allocates from a process-global heap.
The modules might not use the same implementation of std::string. With an object layout that does not match. Easily induced by having the modules compiled with different C++ library versions, particularly an issue with C++11 changes. Or different build settings, the _HAS_ITERATOR_DEBUGGING macro is quite notorious.
The only cure for that problem is to make sure that you build all of the modules in your program with the exact same compiler version using the exact same build settings. Using /MD is mandatory, it ensures that the CRT is shared so there's only one in the program.
The likely cause: binding to wrong version of the Qt DLLs, especially when moving a project from VS2010 to VS2012.
This is due to different versions of the standard library and associated dynamic allocation issues.
I had the same problem after a Windows reinstallation. My Runtime library build was Multi-threaded Debug DLL (/MDd).
My solution was to remove *.user file of the visual studio project, remove the debug folder and rebuild the project.
Hi I'm making a dialog based application in MFC using:
BOOL CClockMasterDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_ModeTabs.Create(this,WS_CHILD | WS_VISIBLE, 0);
}
If I destroy m_ModeTabs in CClockMasterDlg::OnInitDialog function after it is created using :
m_ModeTabs.DestroyWindow();
I get no memory but leaks when I place it in CClockMasterDlg::OnDestroy() I get memory leaks, even tough it gets called and returns true.
I don't believe that OnDestroy is OnInitDialog's contrary, but then which function is? There is no OnExitDialog.
Detected memory leaks!
Dumping objects ->
{601} client block at 0x00AEED48, subtype c0, 212 bytes long.
a CMFCVisualManager object at $00AEED48, 212 bytes long
Object dump complete.
The program [5312] ClockMaster.exe: Native has exited with code 2 (0x2).
Even tough the window should be destroyed automatically since it`s not a pointer I still shouldn't get memory leaks should I? And since placing
m_ModeTabs.DestroyWindow();
in the OnInitDialog function after its created solves the memory leak it cant really be something else causing the trouble can it? Removing the m_ModeTabs.Create(... Also solves the memory leak so I'm quite certain that its m_ModeTabs causing it.
Thought you don't say, I'm assuming that m_ModeTabs is a child window of your CClockMasterDlg. In that case, or similar cases, you don't have to explicitly call DestroyWindow. When a window is Destroy()ed by Win32, all of its child windows are destroyed as well.
Since you declared your m_ModeTabs as a regular variable (not a pointer), the memory owned by it will be freed automatically by the C++ runtime during the destructor of CClockMasterDlg.
I where actually hitting a bug which is gonna be "fixed in MFC for the next major release of Visual Studio".
The memory leak occurs when using a CVSListBox in a dialog only mfc application.
Information on the bug and several workarounds can be found here:
https://connect.microsoft.com/VisualStudio/feedback/details/646445/cvslistbox-produces-memory-leaks
http://connect.microsoft.com/VisualStudio/feedback/details/565327/memory-leaks-using-c
And another report on the bug here:
http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/8870974f-1414-4dd7-b7c3-a1c320c0e91e
Quotation from first link:
Hello,
Thanks for the report. This issue has been fixed in MFC for the next
major release of Visual Studio.
Pat Brenner Visual C++ Libraries Development
I wrote my own reference counted memory manager c++ (for fun) and I'm sure it isn't perfect ;) . And now when I'm trying to use it I got random SIGTRAP signals. If I comment out every line which are in connection with that memory manager everything runs fine. Getting SIGTRAP-s instead of SIGSEGV is quite strange.
I know that SIGTRAP-s are thrown when the program hits a breakpoint, but no breakpoint is set. I read in an other thread that debug builds of the exe's and dll's must be up to date. They are up to date and so it is not the reason.
Does anyone know why is this happening?
After searching on Google I realized that those sigtraps are same as those warnings you get in MSVC++ saying "Windows has triggered a breakpoint in xxxx.exe. This may be due to a corruption of the heap, and indicates a bug blahblahblah"...
So it seems yes, unexpected sigtraps can indicate memory corrupction (quite strange...)
And I found my bug too. The MM is in a static library which is linked to a dll. And that static lib and the dll is linked to my exe. So there were two memory managers, one in my exe and one in my dll. If call the initaialization method of the MM. It initialized the MM in my exe but not in the dll so the dll went without init. I solved this by not linking my exe against that static library.
I'd throw in a guess that you might be calling mismatched new/delete or malloc/free implementations - So something was allocated by your memory manager but when the memory is released you end up with the default delete/free implementation.
Set a breakpoint on the signal and see whether there is free() or operator delete on the stack and whether that is the implementation of said function which you would expect.
Platform : Win32
Language : C++
I get an error if I leave the program running for a while (~10 min).
Unhandled exception at 0x10003fe2 in ImportTest.exe: 0xC0000005: Access violation reading location 0x003b1000.
I think it could be a memory leak but I don't know how to find that out.
Im also unable to 'free()' memory because it always causes (maybe i shouldn't be using free() on variables) :
Unhandled exception at 0x76e81f70 in ImportTest.exe: 0xC0000005: Access violation reading location 0x0fffffff.
at that stage the program isn't doing anything and it is just waiting for user input
dllHandle = LoadLibrary(L"miniFMOD.dll");
playSongPtr = (playSongT)GetProcAddress(dllHandle,"SongPlay");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");
int songHandle = loadSongPtr("FILE_PATH");
// ... {just output , couldn't cause errors}
playSongPtr(songHandle);
getch(); // that is where it causes an error if i leave it running for a while
Edit 2:
playSongPtr(); causes the problem. but i don't know how to fix it
I think it's pretty clear that your program has a bug. If you don't know where to start looking, a useful technique is "divide and conquer".
Start with your program in a state where you can cause the exception to happen. Eliminate half your code, and try again. If the exception still happens, then you've got half as much code to look through. If the exception doesn't happen, then it might have been related to the code you just removed.
Repeat the above until you isolate the problem.
Update: You say "at that stage the program isn't doing anything" but clearly it is doing something (otherwise it wouldn't crash). Is your program a console mode program? If so, what function are you using to wait for user input? If not, then is it a GUI mode program? Have you opened a dialog box and are waiting for something to happen? Have you got any Windows timers running? Any threads?
Update 2: In light of the small snippet of code you posted, I'm pretty sure that if you try to remove the call to the playSongPtr(songHandle) function, then your problem is likely to go away. You will have to investigate what the requirements are for "miniFMOD.dll". For example, that DLL might assume that it's running in a GUI environment instead of a console program, and may do things that don't necessarily work in console mode. Also, in order to do anything in the background (including playing a song), that DLL probably needs to create a thread to periodically load the next bit of the song and queue it in the play buffer. You can check the number of threads being created by your program in Task Manager (or better, Process Explorer). If it's more than one, then there are other things going on that you aren't directly controlling.
The error tells you that memory is accessed which you have not allocated at the moment. It could be a pointer error like dereferencing NULL. Another possibility is that you use memory after you freed it.
The first step would be to check your code for NULL reference checks, i.e. make sure you have a valid pointer before you use it, and to check the lifecycle of all allocated and freed resources. Writing NULL's over references you just freed might help find the problem spot.
I doubt this particular problem is a memory leak; the problem is dereferencing a pointer that does not point to something useful. To check for a memory leak, watch your process in your operating system's process list tool (task manager, ps, whatever) and see if the "used memory" value keeps growing.
On calling free: You should call free() once and only once on the non-null values returned from malloc(), calloc() or strdup(). Calling free() less than once will lead to a memory leak. Calling free() more than once will lead to memory corruption.
You should get a stack trace to see what is going on when the process crashes. Based on my reading of the addresses involved you probably have a stack overflow or have an incorrect pointer calculation using a stack address (in C/C++ terms: an "auto" variable.) A stack trace will tell you how you got to the point where it crashed.