PDA

View Full Version : To use or not to use: deleteLater()



codeslicer
10th July 2009, 03:33
--First off, this might be a Newbie question, but it might not, so feel free to move it.

Anyways, in my application I have a variety of objects (like QSettings) and I think deleting them after they're used is a good way to free up memory. So, it seems I can't delete an object without an error being generated or my app freezing later.

So one time, I have an object defined in my header:



...
private:
settings settingsChanger;
...


The "settings" class is a QObject subclass that has a single QSettings object defined in the header and contains a variety of members to change values in QSettings. So, in my code after I'm done with settingChanger, naturally I want to delete it. So I use deleteLater() but my program just has a "signal" and the debugger stops it.

Doing the same thing with a pointer to the object, and having



...
private:
settings *settingsChanger;
...


And in the definition:


...
settingsChanger = new settings(this);
...
settingsChanger->deleteLater()
...


causes my program to get a signal too. So, I'm not really sure what I'm doing wrong. :crying: Should I delete the QSettings in the destructor of my settings class? I thought deleteLater() was a complete failsafe that wouldn't cause problems like this, but am I wrong, or have I made a huge mistake?

Thanks in advance for any advice. :o

~codeslicer

nish
10th July 2009, 03:59
you should call deleteLater() just like at place where you call delete()...

deleteLater() can delete your object at any time. You ask qt that you do not need the object and qt can delete it anytime(may be instantly)..

so


object = new Object
object->useIt();
delete object;
object->useIt();//ERROR the object is deleted.

and this is same as above

object = new Object
object->useIt();
object->deleteLater();//Qt will delete it at any time ... may be just now.
object->useIt();//ERROR the object is deleted.

therefore use deleteLater in a place after which you will never use the object(destructor?)


EDIT:-
i was too quick... i just saw u said that you are done with settings object when you call deleteLater().. so may be just check that the object is not refrenced anywhere else

nish
10th July 2009, 04:05
So one time, I have an object defined in my header:



...
private:
settings settingsChanger;
...


The "settings" class is a QObject subclass that has a single QSettings object defined in the header and contains a variety of members to change values in QSettings. So, in my code after I'm done with settingChanger, naturally I want to delete it. So I use deleteLater() but my program just has a "signal" and the debugger stops it.



oh i forgot to mention that you cannot delete objects which are on stack

codeslicer
10th July 2009, 13:42
oh i forgot to mention that you cannot delete objects which are on stack

Wow never knew that. I sort of taught C++ myself so I guess I skipped learning some of the newbie things. So does that mean it's better to make "new" objects because those can be deleted? Or only reserve smaller objects (like bool and int) for the stack?

I guess I'll check to make sure the object isn't used elsewhere after deleting it.

But thanks for your help, I'll try that soon... :)

dpimka
10th July 2009, 14:05
deleteLater() can delete your object at any time. You ask qt that you do not need the object and qt can delete it anytime(may be instantly)..

Hmm, I thought that deleteLater() always deletes object on next event loop iteration, so it never happens "instantly" after being issued. Or am I wrong? :)

codeslicer
10th July 2009, 15:10
Hmm, I thought that deleteLater() always deletes object on next event loop iteration, so it never happens "instantly" after being issued. Or am I wrong? :)

deleteLater() can delete your object at any time when the event loop has control, sometimes that can be instantly if there aren't any other events.

nish
10th July 2009, 16:19
deleteLater() can delete your object at any time when the event loop has control, sometimes that can be instantly if there aren't any other events.

looks like you learn very fast :)



So does that mean it's better to make "new" objects because those can be deleted? Or only reserve smaller objects (like bool and int) for the stack?

this is a tricky question.
in qt any class which is derived from qobject can have children(fox example a QDialog containg Ok,Cancel button as its children). Now when the qdialog is deleted, it also deletes all its children,,, if the children are on stack that will cause crash. So all the QObjects derived classes which will become child of any object in your program should be on heap.

but this is not general rule. many times a local child widget is created on stack(for example a temporary messagebox)

wysota
10th July 2009, 17:06
Wow never knew that. I sort of taught C++ myself so I guess I skipped learning some of the newbie things. So does that mean it's better to make "new" objects because those can be deleted? Or only reserve smaller objects (like bool and int) for the stack?

Objects allocated on stack are deleted by the compiler once you exit the scope they were declared in. Objects allocated on heap are "persistant" and are not deleted by the compiler - you are responsible for deleting them yourself unless there is some mechanism that does it for you (like a garbage collector or Qt's memory management). So it's actually better to allocate objects on stack because you don't have to care about them being deleted but unfortunately it is not always possible to use stack based objects only.

codeslicer
10th July 2009, 20:29
Thanks for the replies, I just have one little question.

MrDeath said if you delete an object which is on stack and it has children on stack then the program will crash. So the only objects that should be on stack are those that don't have any children?

Thanks!

wysota
11th July 2009, 09:29
So the only objects that should be on stack are those that don't have any children?

No, it's the other way round. The only objects on the stack should be the ones that don't have a parent with exception of QDialog which is a short living object and will be deleted before the scope of its parent ends.

codeslicer
11th July 2009, 14:49
Alright thanks a lot, I really understand how this works. One more thing (sorry :P). I heard it's best to dereference a pointer after the object is deleted. If you use deleteLater() is it necessary to do that? Like here:



myObject = new object(this);

...

myObject->deleteLater();
myObject = 0;


Or only use that with delete?

Thanks once again. :D

dpimka
11th July 2009, 21:43
First: You misunderstood the meaning of the word "dereference" :) Dereferencing means getting a value of the pointer by using a "*" operator. For example:


QObject *obj = new QObject;
qDebug() << *obj; // <-- this is a dereferencing of the "obj" pointer


Second: Guessing that you asked if it is needed to assign 0 to the pointer after object has been deleted, the answer is: this is handy if your pointer can be potentially used in other places in code (for example if it is a member of some class). In these situations you can check if that object is already deleted. And delete or deleteLater doesn't make difference: Assigning 0 is used only to be able to tell if that ptr still exists or not. Examples:



void myFunction()
{
MyClass* obj = new MyClass;
// some action...
delete obj;
// obj = 0 <-- doesn't make sense, function will end and no one will ever know about obj as it is a local variable
}




class SomeClass
{
private:
QObject* m_obj;

public:
void func1()
{
m_obj = new QObject;
// some action
delete m_obj;
m_obj = 0;
}
void func2()
{
// try to use m_obj, but check if it really exists
if( m_obj )
// do some stuff
else
qDebug() << "oops, m_obj is already deleted";
}
}