Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, October 2007
Bug with heap-based memory allocation


Message 1 in thread

Hi, I'm quite new to Qt, thus please excuse me if my question is trivial.

I'm running under SuSE Linux 9.0, with g++ (GCC) 3.4.6


I just modified the example #1 of the tutorial in t1/main.cpp, in such
a way that it uses exclusively heap-based allocations :
[[
#include <QApplication>
#include <QPushButton>

QApplication *app;
void init(int argc, char *argv[]) {
  app=new QApplication (argc, argv);
}
int main(int argc, char *argv[])
{
    init(argc, argv);

    QPushButton *hello=new QPushButton("Hello world!");
    hello->resize(100, 30);

    hello->show();
    return app->exec();
}
]]


When I run this program, it crashes. Can somebody tell
me if this is expected, or if it is not ?


Best, Henri


P.S. : The strange thing is that if I move the content of
the init() function above inside the main, or if I turn it
to an inline function, then the crash disappears.

This evokes either a subtle bug in the current release
of Qt, or either a problem with my compiler version,
or either there is something I didn't understood...


--
 [ signature omitted ] 

Message 2 in thread

I saw this problem too when porting from QT3 to QT4.  It crashes because
argc is being destroyed before QApplication can use it.  Apparently
QApplication saves a reference to those variables instead of copies.
The fix is to change your init function to . . .

void init(int & argc, char * argv []) {
  app=new QApplication (argc, argv);
}

Noticed the "&" in front of argc.

-----Original Message-----
From: Henri Lesourd [mailto:lesourd@xxxxxxxxxxx] 
Sent: Monday, October 15, 2007 13:38
To: qt-interest@xxxxxxxxxxxxx
Subject: Bug with heap-based memory allocation


Hi, I'm quite new to Qt, thus please excuse me if my question is
trivial.

I'm running under SuSE Linux 9.0, with g++ (GCC) 3.4.6


I just modified the example #1 of the tutorial in t1/main.cpp, in such
a way that it uses exclusively heap-based allocations :
[[
#include <QApplication>
#include <QPushButton>

QApplication *app;
void init(int argc, char *argv[]) {
  app=new QApplication (argc, argv);
}
int main(int argc, char *argv[])
{
    init(argc, argv);

    QPushButton *hello=new QPushButton("Hello world!");
    hello->resize(100, 30);

    hello->show();
    return app->exec();
}
]]


When I run this program, it crashes. Can somebody tell
me if this is expected, or if it is not ?


Best, Henri


P.S. : The strange thing is that if I move the content of
the init() function above inside the main, or if I turn it
to an inline function, then the crash disappears.

This evokes either a subtle bug in the current release
of Qt, or either a problem with my compiler version,
or either there is something I didn't understood...


--
 [ signature omitted ] 

Message 3 in thread

On Monday 15 October 2007 23:20:08 Jones, Torrin A (US SSA) wrote:
> The fix is to change your init function to . . .
>
> void init(int & argc, char * argv []) {
>   app=new QApplication (argc, argv);
> }
>
> Noticed the "&" in front of argc.


I was close to object (this reasoning seems to be just strange) but the docs 
state:

   QApplication::QApplication ( int & argc, char ** argv )
   Warning: The data pointed to by argc and argv must stay valid 
   for the entire lifetime of the QApplication object.

Thus, after initialization of QApplication with a copy of argc, which goes out 
of scope after init() finishes, some internal state goes haywire. 

Shot in the dark: this may be related to argument handling that QApplication 
removes Qt-specific arguments from argv and thus updates argc?! 

Regards
	Daniel


P.S. Henri, as a sidenote: you may want to look at the qApp() macro instead of 
keeping a pointer of your own.

--
 [ signature omitted ] 

Message 4 in thread

-----Original Message-----
From: Daniel Franke [mailto:franke.daniel@xxxxxxxxx] 
Sent: Monday, October 15, 2007 14:55
To: qt-interest@xxxxxxxxxxxxx
Cc: Jones, Torrin A (US SSA); Henri Lesourd
Subject: Re: Bug with heap-based memory allocation

> Thus, after initialization of QApplication with a copy of argc, which
goes out 
> of scope after init() finishes, some internal state goes haywire. 

> Shot in the dark: this may be related to argument handling that
QApplication 
> removes Qt-specific arguments from argv and thus updates argc?! 


I know this sounds strange.  Even I though it was strange, but it turned
out the be the reason.

Here are more details.

It had to do with QT4 passing argc and argv to X11.  I forget which call
it was, but in QT4 it calls some function in X11 that takes argc and
argv as parameters.  That call crashes the app.  When I debugged the
crash I noticed that argc was more than 600,000 and argv was correct.
After my initial "huh?", I did some more debugging and tracing and found
that to be the problem.

We use the exact same code on windows, but it doesn't have this problem.
I guess there's no need to pass argc and argv to X11 if you don't have
X11.  :)  Anyway, after taking a look at the QT4 code I want to say it
crashed in XSetWMProperties() in
QApplicationPrivate::applyX11SpecificCommandLineArguments() in
qapplication_x11.cpp, but it's been so long I can't remember.

NOTE: I read that exact line from the documentation after I debugged the
crash so I didn't report the bug.

NOTE: This didn't happen with QT3.  Only QT4 on UNIX.  Solaris 8 to be
exact.

So, heed the warning in the documentation.

--
 [ signature omitted ] 

Message 5 in thread

Jones, Torrin A (US SSA) wrote:
> It had to do with QT4 passing argc and argv to X11.  I forget which call
> it was, but in QT4 it calls some function in X11 that takes argc and
> argv as parameters.  That call crashes the app.  When I debugged the
> crash I noticed that argc was more than 600,000 and argv was correct.
> After my initial "huh?", I did some more debugging and tracing and found
> that to be the problem.

It is due to an API bug in QApplication. The definition is as,

QApplication( int & argc, char **argv ...... ) .....

argc is a reference instead of a value and that is what screws 
everything up. The init function disappears, and the reference now 
points to nowhere.

Remember, (int&) is internally a *(int*).

So, nothing really to do with X11 or Windows/UNIX/OS X. The definition 
should not use a reference unless it takes a value internally in the 
constructor.

> NOTE: This didn't happen with QT3.  Only QT4 on UNIX.  Solaris 8 to be
> exact.

Qt3 had exactly the same problem.

   QApplication ( int & argc, char ** argv )

maybe it just didn't show up because argc was not used after 
initialization or it was internally stored as a number instead of a 
reference.

Personally, int & is completely useless when pointing to read-only 
variables. On many systems it will be more efficient to pass int instead 
of int& as a pointer takes more space than int. For example, amd64, 
sizeof(int*) = 8 while sizeof(int)=4 AFAIK. No diff on 32-bit systems 
except for headaches.

Cheers,
Adam

--
 [ signature omitted ] 

Message 6 in thread

Em Tuesday 16 October 2007 01:45:21 Adam M escreveu:
> So, nothing really to do with X11 or Windows/UNIX/OS X. The definition
> should not use a reference unless it takes a value internally in the
> constructor.

It modifies your argc.

> Personally, int & is completely useless when pointing to read-only
> variables. On many systems it will be more efficient to pass int instead
> of int& as a pointer takes more space than int. For example, amd64,
> sizeof(int*) = 8 while sizeof(int)=4 AFAIK. No diff on 32-bit systems
> except for headaches.

I agree with you: int & is useless when pointing to read-only variables.

In this case, it's not read-only. It's read-and-write.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 7 in thread

Thiago Macieira wrote:

>Em Tuesday 16 October 2007 01:45:21 Adam M escreveu:
>  
>
>>So, nothing really to do with X11 or Windows/UNIX/OS X. The definition
>>should not use a reference unless it takes a value internally in the
>>constructor.
>>    
>>
>
>It modifies your argc.
>  
>
> [...]
>
>I agree with you: int & is useless when pointing to read-only variables.
>
>In this case, it's not read-only. It's read-and-write.
>  
>
OK, for some (non self-evident) reason, this variable is read-only.

Logically speaking, you are right. But in practice, these kinds of things
should be banned from any sane API. Really, when you start hacking
with a new library, you should not risk encountering such issues hidden
somewhere in one of the most basic routines...

Too bad, all the more because that for all the rest, the philosophy of Qt
seems to emphasize simplicity and help the user to do easily the simple
things.

--
 [ signature omitted ] 

Message 8 in thread

Jones, Torrin A (US SSA) wrote:

>>Thus, after initialization of QApplication with a copy of argc, which
>>    
>>
>goes out 
>  
>
>>of scope after init() finishes, some internal state goes haywire. 
>>    
>>
>I know this sounds strange.  Even I though it was strange, but it turned
>out the be the reason.
>
>  
>
Wow.

Thanks you very much for the hint, this is the kind of sh!@#y things
that can take lots of time to find (especially if you really want to 
understand
exactly what's happening and you dont know the environment).

But I was pretty sure there was a quite precise thing to understand in this.


Thanks again, Henri

--
 [ signature omitted ]