I have a QList of pointers objects which are inherited from QThread in a multi-threaded application. For example:
QList<Object*> m_threadList;
and
class Object: QThread
However, when all threads finished their execution, I need to delete those pointers in order to prevent memory leak. However it always crashed when the program tries to delete the pointer. The funniest thing is that it does not always happen. I am doing something like following:
for(QList<Object*>::iterator it=m_threadList.begin();it!=m_threadList.end();it++)
{
if(!(*it)->isRunning() && (*it)->isFinished())
{
disconnect((*it),SIGNAL(ResultsProvider(int)),this,SLOT(ResultsListener(int)));
(*it)->exit();
(*it)->deleteLater();
if((*it)!=NULL)
delete (*it); // It always crashes here
}
}
m_threadList.clear(); // will this cause an issue with deleteLater?
This crash does not happen always. Without changing anything, sometimes it will crash when it is trying to delete the pointer and sometimes it will go through smoothly. Has anybody faced similar problem before using any sort of container to store pointer objects (especially QThread)? or can anybody tell where can the problem be?
Related
When my objects are destroyed, I keep getting an Assertion failure in
dbgheap.c line 1399
_ASSERTE(pHead->nBlockUse == nBlockUse);
I can't find any reason why this happens. The pointers are properly initialized to NULL in the constructor:
CPlayThread()
{
m_pPlayer[0]= NULL;
m_pPlayer[1]= NULL;
};
This is the code that actually creates the objects.
if(pParam->m_pPlayer[0] == NULL) //pParam is a CPlayThread*
{
if(config.m_nPlayerMode == modeSocket)
pParam->m_pPlayer[0]= new CSocketPlayer();
}
The objects get destroyed when the thread is destroyed, and this is where the assertion occurs.
~CPlayThread()
{
if(m_pPlayer[0])
delete m_pPlayer[0];
m_pPlayer[0]=NULL;
if(m_pPlayer[1])
delete m_pPlayer[1];
m_pPlayer[1]= NULL;
};
I'm at a total loss here. It used to work fine and somehow it started crashing at a client's location after three or four days of running continously. At the same time my debug executable started asserting every
single time a player was destroyed. There are up to 96 threads that might be playing at any given time (with two players each thread, alternating - the players were created and destroyed as needed). So after looking for a solution and not finding one, I decided to just keep the objects for the duration of the application exectution. So now I only get the assertion when I close the debug version of the program (and presummably there is an unnoticeable crash on closing the release version, which is never because this should run 24/7).
I just need to know what I am doing wrong. Any help would be appretiated.
What type is m_pPlayer[0] ( Like David asked. ) is it a base type of CSocketPlayer or is it CSocketPlayer itself. ? If it's a base type you need to make the destructor in the base class virtual. That might be related to your problem. If not, then the problem must be that you already deleted the object. This can be due to a racing condition, where 2 threads run the destructor with the same pointers.
What also could be is that either the new or delete operator is overloaded, for example allocating from another heap. Guess that is far fetched .... but possible ..
I am developing a gui proram using Qt 4.7.4 (64 bit). I have tried to isolate the problem as follows:
I have a window: class PreferencesWindow : public QMainWindow and in another class I initialize and show it as
QSharedPointer<PreferencesWindow> pPreferencesWindow = QSharedPointer<PreferencesWindow>(new PreferencesWindow());
pPreferencesWindow->show();
it is all good, then I close the window either by pressing ESC or clicking the x button on the window. And then I call
QApplication::quit();
to terminate the whole program. It terminates but gives a segmentation fault just before terminating.
The question here is why it terminates cleanly when I use regular pointer instead of QSharedPointer and how to use QSharedPointer properly in this case?
I suspect the problem is that when you close the window, the data structure pointed to by pPreferencesWindow is deleted without the QSharedPointer's knowledge. When the QSharedPointer itself is later destroyed, it double-deletes the window, and you get the segfault.
Basically, as with all shared pointer implementations, either everybody plays, or nobody does. Since the Qt internals will never know you're using a smart pointer to manage the window, you can't use one. This is a blessing in disguise, however; it means that Qt itself takes possession of the pointer and agrees to manage it for you, so you don't need a smart pointer after all!
I am not an expert with Qt but my first thoughts would be that QMainWindow deletes itself upon destruction and the QSharedPointer object will also delete the object when it's destroyed (i.e. the object is deleted twice). If this is true you don't need to use the QSharedPointer at all.
EDIT: It looks like the QtWidget Qt::WA_DeleteOnClose flag will cause the behaviour I have described.
Or at least I think the problem involves some kind of memory error. I'm making a program in SFML and I'm currently working on the menus using a GUI class that I made just for SFML. Internally, the GUI class uses std::shared_ptr to manage all of its internal pointers. The program consistently crashes after main() exits and all global destructors have been called, and gdb says a break point was triggered in ntdll!WaitForAlpCompletion, which leads me to believe that the problem is memory corruption. Whenever I remove the GUI instantiation from the menu function, it exits and closes with no errors. This seems to indicate GUI as the cause of the crash, except that sub-menus which create and destroy their own instances of GUI can be called and exited without any crashes or break points.
Some psuedocode:
SubMenu
{
Create GUI
Do Menu
Destroy GUI
}
Menu
{
Create GUI
Do Menu?SubMenu
Destroy GUI
}
main
{
Init Stuff
Menu
UnInit Stuff
Destroy GUI
return 0
}
//after return
Global Dtors
Breakpoint triggered???
I'm at a loss as to what this could be. I plan on using some memory debugger like valgrind sometime today, but I was wondering if anyone else had any ideas on what this could be.
Finally figured it out!!!!! It turns out that std::map calls the destructors of its objects every time it is re-sized, causing the shared_ptr's within to delete their data several times. A few "quick" design changes and fixed :) Thanks guys!
A heap corruption can be caused with this code:
int main()
{
int *A(new(std::nothrow) int(10));
int *B(A);
delete B;
delete A;
}
Does any of your code contain this similar situation?
I've got a private ref count inside the class SharedObject. SharedObject is a base class for other classes, for example Window. Window is the base class of Editor.
When the ref count reaches 0, because of calling SharedObject::Release(), the SharedObject deletes itself. First we get to the Editor destructor, which shows that the this pointer contains m_refs == 0, but when we get to the Window destructor it is suddenly 1, and when we reach the SharedObject destructor, it is still 1.
I put a breakpoint on the SharedObject::IncRef() method, and it was never called while this happened.
What the?
Build with optimizations off, and set a memory breakpoint on your m_refs.
Seems like you have memory leak somewhere, maybe even long before this destruction occurs. I use Alleyoop to find leaks. Can help, won't hurt to have that out of the way.
Do you use multiple threads? Maybe it's due to some raw pointer somewhere being grabbed by other thread during destruction.
On a side note, I recommend using boost::intrusive_ptr - very convinient pattern for handling addrefs and releases in shared objects that helps to be consequent with it, but this probably won't solve your problem unless you have a real mess in your code ;)
I'm getting a bad error. When I call delete on an object at the top of an object hierarchy (hoping to the cause the deletion of its child objects), my progam quits and I get this:
*** glibc detected *** /home/mossen/workspace/abbot/Debug/abbot: double free or corruption (out): 0xb7ec2158 ***
followed by what looks like a memory dump of some kind. I've searched for this error and from what I gather it seems to occur when you attempt to delete memory that has already been deleted. Impossible as there's only one place in my code that attempts this delete. Here's the wacky part: it does not occur in debug mode. The code in question:
Terrain::~Terrain()
{
if (heightmap != NULL) // 'heightmap' is a Heightmap*
{
cout << "heightmap& == " << heightmap << endl;
delete heightmap;
}
}
I have commented out everything in the heightmap destructor, and still this error. When the error occurs,
heightmap& == 0xb7ec2158
is printed. In debug mode I can step through the code slowly and
heightmap& == 0x00000000
is printed, and there is no error. If I comment out the 'delete heightmap;' line, error never occurs. The destructor above is called from another destructor (separate classes, no virtual destructors or anything like that). The heightmap pointer is new'd in a method like this:
Heightmap* HeightmapLoader::load() // a static method
{
// ....
Heightmap* heightmap = new Heightmap();
// ....other code
return heightmap;
}
Could it be something to do with returning a pointer that was initialized in the stack space of a static method? Am I doing the delete correctly? Any other tips on what I could check for or do better?
What happens if load() is never called? Does your class constructor initialise heightmap, or is it uninitialised when it gets to the destructor?
Also, you say:
... delete memory that has already been deleted. Impossible as there's only one place in my code that attempts this delete.
However, you haven't taken into consideration that your destructor might be called more than once during the execution of your program.
In debug mode pointers are often set to NULL and memory blocks zeroed out. That is the reason why you are experiencing different behavior in debug/release mode.
I would suggest you use a smart pointer instead of a traditional pointer
auto_ptr<Heightmap> HeightmapLoader::load() // a static method
{
// ....
auto_ptr<Heightmap> heightmap( new Heightmap() );
// ....other code
return heightmap;
}
that way you don't need to delete it later as it will be done for you automatically
see also boost::shared_ptr
It's quite possible that you're calling that dtor twice; in debug mode the pointer happens to be zeroed on delete, in optimized mode it's left alone. While not a clean resolution, the first workaround that comes to mind is setting heightmap = NULL; right after the delete -- it shouldn't be necessary but surely can't hurt while you're looking for the explanation of why you're destroying some Terrain instance twice!-) [[there's absolutely nothing in the tiny amount of code you're showing that can help us explain the reason for the double-destruction.]]
It looks like the classic case of uninitialized pointer. As #Greg said, what if load() is not called from Terrain? I think you are not initializing the HeightMap* pointer inside the Terrain constructor. In debug mode, this pointer may be set to NULL and C++ gurantees that deleting a NULL pointer is a valid operation and hence the code doesn't crash. However, in release mode due to optimizations, the pointer in uninitialized and you try to free some random block of memory and the above crash occurs.