[Kde-bindings] new QApplication and MethodCall cleanup
Richard Dale
rdale at foton.es
Tue Aug 5 09:57:49 UTC 2008
On Tuesday 05 August 2008 10:48:27 Phil Thompson wrote:
> On Tue, 5 Aug 2008 02:17:44 -0700, "Chris Burel" <chrisburel at gmail.com>
>
> wrote:
> > I've been trying to get Hello World! to work in Perl and Qt4 for the past
> > couple weeks, and the problem that I've really been battling is a
>
> segfault
>
> > when I call $label->show(). The backtrace showed it failing in libc's
> > strlen() function. I eventually traced it down to the fact that since we
> > pass in a char** to the QApplication, when it goes to show the
> > application,
> > it tries to access the data stored by that pointer. But in the PerlQt3
> > code, and qtruby4, the MethodCall object cleanup() method returns true,
>
> so
>
> > that memory has already been cleared by the marshall_charP_array handler
> > fn
> > ('rb_ary_clear(arglist);' in qtruby and by 'av_clear(arglist);' perlqt3).
> >
> > How is this working? As soon as I change the MethodCall cleanup() method
> > to
> > return false, the $label->show works fine. Obviously that's not the real
> > solution, and the other bindings are getting around this somehow.
>
> I'm not sure if it's the same issue, but Qt4's QApplication ctors keep a
> pointer to the argc parameter and dereference it later on. With C++ argc is
> on the stack but that's Ok because that part of the stack will never be
> popped until the application exits. With other languages argc is more
> likely to be on the heap and to be garbage collected too soon.
>
> The PyQt solution is to save argc in a local static int and pass that to
> the QApplication ctors.
This is the code in QtRuby that creates the argc 'char **' array given a Ruby
Array of strings:
char **argv = new char *[RARRAY(arglist)->len + 1];
long i;
for(i = 0; i < RARRAY(arglist)->len; i++) {
VALUE item = rb_ary_entry(arglist, i);
char *s = StringValuePtr(item);
argv[i] = new char[strlen(s) + 1];
strcpy(argv[i], s);
}
So it mallocs the array of char *s, and then creates a new copy of the Ruby
StringValuePtr that contains the data in each Ruby String.
It doesn't attempt to delete the 'argv' array after the call. The code after
cleanup just recreates the Ruby array from whatever was in the argv array
after the call:
rb_ary_clear(arglist);
for(i = 0; argv[i]; i++) {
rb_ary_push(arglist, rb_str_new2(argv[i]));
}
I think the assumption is that a 'char **' argument type will always expect to
hang around after the call for the life of the program and that a leak is
acceptable. I don't think I know of any cases in the Qt or KDE apis where
they are expected to only be around for the life of the method call. I would
hope that a QStringList is usually used instead.
-- Richard
More information about the Kde-bindings
mailing list