maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Development (https://talk.maemo.org/forumdisplay.php?f=13)
-   -   Qt: ridiculous behaviour (https://talk.maemo.org/showthread.php?t=49468)

Venemo 2010-04-07 21:31

Qt: ridiculous behaviour
 
Hi,

I'm pretty new to Qt development, and I've just encountered something that I wasn't able to figure out for hours.

How come that the following code doesn't work:
Code:

QNetworkRequest request(QUrl("http://venemo.net/Default.aspx"));
QNetworkAccessManager manager(this);
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
manager.get(request);

while the following does:
Code:

QNetworkRequest request(QUrl("http://venemo.net/Default.aspx"));
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
manager->get(request);

I think that both syntaxes SHOULD do the same, or at least, when I was at university, they did at my C++ course.

Can anyone elaborate on this?

StewartHolmes 2010-04-07 21:43

Re: Qt: ridiculous behaviour
 
The difference in your code is that in one, you create the QNetworkManager on the stack

QNetworkManager m;

and in the other you create it on the heap

m = new QNetworkManager();

When you create on the stack, at the end of the current closure, the memory will be freed, and the ~QNetworkManager() method called.

hqh 2010-04-07 21:51

Re: Qt: ridiculous behaviour
 
It's not exactly the same. In first case the manager object gets automatically deleted when it goes out of scope (that is, when '}' is reached if I remember correctly).

In the second case the manager object (to which the pointer refers to) allocated with "new" never gets deleted unless "delete" is used on it. It results in memory leak if you forget to delete it.

Venemo 2010-04-07 21:55

Re: Qt: ridiculous behaviour
 
Thanks!

Indeed, those C++ courses were quite long ago.

I forgot that the QNetworkManager instance is destroyed after the function call ends, and it really shouldn't be destroyed because it is requred to call back the finished event.

I feel so ashamed now... :(

saxen 2010-05-19 06:48

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by StewartHolmes (Post 600061)
The difference in your code is that in one, you create the QNetworkManager on the stack

QNetworkManager m;

and in the other you create it on the heap

m = new QNetworkManager();

When you create on the stack, at the end of the current closure, the memory will be freed, and the ~QNetworkManager() method called.

Sorry for (maybe) stupid question...i'm new with c++! when using one instead of the other?
i mean, is it only a difference in term of memory allocation??

gri 2010-05-19 06:54

Re: Qt: ridiculous behaviour
 
Objects on the stack don't need to be deleted.

Code:

// returns dead pointer (obj dies when leaving function)
QObject* function()
{
  QObject obj;
  return &obj;
}

// returns valid pointer (the return value has to be "delete"d)
QObject* function()
{
  return new QObject;
}

In case of the QNetworkManager this means: The request is started via the manager but the manager dies at the function end. So the request never comes back.

saxen 2010-05-19 07:07

Re: Qt: ridiculous behaviour
 
thanks for reply! what if a pointer(heap allocation) is declared in a method but not returned?? it's not dead, but also out of scope, so not usefull?

i mean:
Code:

void function()
{
  QObject* obj =  new QObject;
  obj->doSomething()
}

is better use stack allocation this time?

gri 2010-05-19 07:20

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by saxen (Post 665466)
thanks for reply! what if a pointer(heap allocation) is declared in a method but not returned?? it's not dead, but also out of scope, so not usefull?

i mean:
Code:

void function()
{
  QObject* obj =  new QObject;
  obj->doSomething()
}

is better use stack allocation this time?

Now your code is a memory leak. The Object still exists on the heap but you can never find it again to delete.

But QObject's have an exception with the deleting: Every QObject deletes it's children when it is deleted. So always do "new QObject(parent)" when possible, then you don't have to care about memory freeing.

gusch5 2010-05-19 07:28

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by saxen (Post 665466)
Code:

void function()
{
  QObject* obj =  new QObject;
  obj->doSomething()
}


This is called a memory leak ;)
And my advice: if you ask yourself if heap or stack should be used, the stack is mostly the better solution.

saxen 2010-05-19 07:33

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by gri (Post 665488)
But QObject's have an exception with the deleting: Every QObject deletes it's children when it is deleted. So always do "new QObject(parent)" when possible, then you don't have to care about memory freeing.

where "parent" could be the class containing it? such a widget?
so with this trick i don't need to call explicitly delete on every object but just on "main objects"?!

thanks for help! i'm missing java garbage collector :o

gri 2010-05-19 07:57

Re: Qt: ridiculous behaviour
 
Parent can be any class that inherits from QObject. QWidgets are inherited from QObject, so yes.
If you create a dialog, give all member pointer variables the dialog as parent and you don't have to care about their memory :)
With Qt the memory handling is a lot easier than with blank c++.

PS: You could also take a look at QSharedPointer when using non-QObject classes. (or boost::shared_ptr if you don't like the Qt implementation)

attila77 2010-05-19 08:08

Re: Qt: ridiculous behaviour
 
Qt also provides some convenience classes for people wishing more pointer automatism:

http://doc.qt.nokia.com/4.6/qscopedpointer.html

http://doc.qt.nokia.com/4.6/qsharedpointer.html

Not exactly garbage collection, but it's as close as it gets to it in 'standard' C++.

saxen 2010-05-19 08:38

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by gri (Post 665586)
Parent can be any class that inherits from QObject. QWidgets are inherited from QObject, so yes.
If you create a dialog, give all member pointer variables the dialog as parent and you don't have to care about their memory :)
With Qt the memory handling is a lot easier than with blank c++.

so in constructor method i've to define:

className(parameters, QObject parent);

am i right?

gri 2010-05-19 08:45

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by saxen (Post 665640)
so in constructor method i've to define:

className(parameters, QObject parent);

am i right?

Not sure what you mean.

example implementation code:
Code:

MyClass::MyClass(QObject* parent)
: QObject(parent) // Not passing the parent to the QObject base will also result in memory leakage
{
    mySubObject = new QObject(this); // Will be deleted when "MyClass" dies
    myLeakObject = new QObject; // Will live forever
}


saxen 2010-05-19 08:53

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by gri (Post 665655)
Not sure what you mean.

example implementation code:
Code:

MyClass::MyClass(QObject* parent)
: QObject(parent) // Not passing the parent to the QObject base will also result in memory leakage
{
    mySubObject = new QObject(this); // Will be deleted when "MyClass" dies
    myLeakObject = new QObject; // Will live forever
}


yes, that's what i meant!! really thanks :)

saxen 2010-05-19 13:46

Re: Qt: ridiculous behaviour
 
while i'm bothering you with this silly questions, i've another doubt about inclusions :o

how to use #include? i mean it's different from java import, so using include(from what i remember) means include "piece of code"(correct if i'm wrong) and not just import a name space!

so, how to avoid duplicate include?
suppose i have main class, firstclass and secondclass, if i include secondclass in firstclass, and first class in main, does main class automatically include secondclass?

i hope u can understand what i'm trying to say :o

damnshock 2010-05-19 14:27

Re: Qt: ridiculous behaviour
 
Quote:

Originally Posted by saxen (Post 666061)
while i'm bothering you with this silly questions, i've another doubt about inclusions :o

how to use #include? i mean it's different from java import, so using include(from what i remember) means include "piece of code"(correct if i'm wrong) and not just import a name space!

so, how to avoid duplicate include?
suppose i have main class, firstclass and secondclass, if i include secondclass in firstclass, and first class in main, does main class automatically include secondclass?

i hope u can understand what i'm trying to say :o

#include is macro directive, an it does what it says: *includes*. You'll make your program bigger in size


#ifndef H_WHATEVER
#define H_WHATEVER


//CODE

#endif

Does this solve your problem?

PS:I'm too learning C++ to develop with Qt :)

gri 2010-05-19 17:11

Re: Qt: ridiculous behaviour
 
You can also use "#pragma once" instead of the ifndef guards. But this is not supported by every compiler.
So with ifndefs you are on the safe side, with pragma once you type less ... of course, you could also use both of them in one file.

Joorin 2010-05-19 18:50

Re: Qt: ridiculous behaviour
 
Compilation of C++ (and C) happens in a couple of different steps:

- Preprocessor (handles #include, #define, #if, #ifdef and the like)
- Compiler (parses all the code and builds an abstract representation, AST, that's then changed in different ways for some kinds of optimization and other compiler magic)
- Generate assembler (the compiler backend translates the AST to platform specific assembler)
- Assembler (the assembler read the assembly code and translates it into object code with link references as special markers)
- Linker (links the compilation units (object code blobs) together and fixes link markers to reference shared libraries)

The preprocessor can be thought of as just a file manipulator that puts together the file that is to be parsed by the compiler. #include is a character by character insertion of another file.

As explained above, #ifdef is the classical way of preventing multiple includes.


All times are GMT. The time now is 04:14.

vBulletin® Version 3.8.8