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
Related
Was passed a set of rendering library that is coded with OSG library and run on Window Environment.
In my program, the renderer exists as a member object in my base class in C++. In my class initiation function, I would do all the neccessary steps to initialize the renderer and use the function this renderer class provide accordingly.
However, I have tried to delete my base class, I presumed the renderer member object would be destroyed along with it. However, when I created another instance of the class, the program would crash when I try to access the rendering function within the renderer.
Have enquired about some opinions on this matter and was told that in Windows, upon deleting the class, the renderer would need to release its glContext and this might be indeterminant time in Windows environment pending upon hardware setup
Is this so? If so, what steps could I take beside amending the rendering source code(if I could get it) to resolve the issue?
Thanks
Actually not deleting / releasing the OpenGL context will just create some memory leak but nothing more. Leaving the OpenGL context around should not cause a crash. In fact crashes like yours are often the cause of releasing some object, that's still required by some other part of the program, so not releasing stuff should not be a cause for a crash like yours.
Your issue is looking more like screwed constructor/destructor or operator= then a GL issue.
its just a gues without the actual code to see/test
Most likely you are accessing already deleted pointer somewhere
check all dynamic member variables and pointers inside your class
Had similar problems in the past so check these
trace back pointers in C++
bds 2006 C hidden memory manager conflicts (class new / delete[] vs. AnsiString)
I recommend to take a look at the second link
especially mine own answer, there is nice example of screwed constructor there
Another possible cause
if you are mixing window message code with threads
and accessing visual system calls or objects within threads instead of window code
that can screw up something in the OS and create unexpected crashes ...
at least on windows
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.
I'm currently facing an issue with VS08. I got the following (simplified) class structure:
class CBase
{
public:
virtual void Func() = 0;
};
class CDerived : public CBase
{
public:
void Func();
};
This code is working fine in Release Mode, but when I try to run a Debug Build it's instantly crashing at new CDerived.
Further Analysis brought me to the point where I was able to locate the crash. It's crashing at CBase::CBase (the compiler-generated constructor). More precisely it's crashing at 04AE46C6 mov dword ptr [eax],offset CBase::vftable' (505C2CCh) `.
Any clues? Release Mode is fine, but I can't properly Debug with it.
Release Mode is fine
Nope, it appears to be fine. My guess is in debug the memory is overwritten somehow. Since there's no way to tell just from the code you posted, here's what you can do.
I assume you create the object somewhere with:
CBase* p = new CDerived;
or similar. In debug mode, set a memory breakpoint at p's location. You can set it to monitor 4 bytes. Visual C++ (like most compilers) will keep the vfptr as the first thing in the class, so this breakpoint will track whether that location overwritten. If the breakpoint is hit before you call the function where it crashes, there's your problem (and the call-stack will show you why it's overwritten).
It could be a lot of reasons - you could be overrunning some memory and overwriting the object (as Erik suggested) - the release version might resolve the call directly to prevent the overhead of the dynamic dispatch and that would explain why it's not crashing.
It could also be that you call delete on the object and the debug version actually zeroes out the memory, whereas the release version doesn't. No way to tell just from that.
Necro-posting a bit here, but there's a point I want to make for future visitors...
As others have said, this was probably a memory corruption or free+reuse issue. You should not assume that it was a compiler bug just because you were able to eliminate the crash by changing compiler settings or rearranging code. If this is a corruption bug, what you probably did was to move the corruption to some memory that does not cause your program to crash--not in your current build, on your current OS & architecture, anyway.
Simply getting to the point of not crashing may have been sufficient for your immediate needs, but meanwhile you did not learn to avoid whatever practice led you to write the bug in the first place. There's a long-standing proverb amongst engineers and probably a fair number of other disciplines:
"What goes away by itself can come back by itself."
It may be one of the most true and important proverbs in any form of engineering. If you did not see the bug die, by your own hand, you should always feel anxious about it. It should bother you, deeply. The bug is probably still there, waiting for the night of your next milestone before it rears its head again.
Luchian Grigore gave good advice on finding the real problem with a memory breakpoint.
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.
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.