[Qt-jambi-interest] Tracking down a problem in native-code
Gunnar Sletta
gunnar at trolltech.com
Mon Nov 10 10:18:56 CET 2008
Tom Schindl wrote:
> Hi,
>
> Well I now found how I can make my example not crash when I modify my
> remove-method from:
>
>> public void remove(ModelElement element) {
>> System.err.println("Removing: " + element);
>> QListWidgetItem item = findItem(element);
>> if( item != null ) {
>> ((QListWidgetItemImpl)item).data = null;
>> listWidget.removeItemWidget(item);
>> }
>> }
removeItemWidget, removes a widget set on the item, not the item itself.
To remove an item from a list you need to use takeItem(). In this
scenario you haven't actually changed the listwidgets itemset at all.
> to
>
>> public void remove(ModelElement element) {
>> System.err.println("Removing: " + element);
>> QListWidgetItem item = findItem(element);
>> if( item != null ) {
>> ((QListWidgetItemImpl)item).data = null;
>> item.dispose();
>> }
>> }
>
> everything works. Looks like a the garbage collection is to working
> appropriately. Is 2nd snippet correct, Gunnar?
When you explicitly call dispose() you will call the destructor of the
item, which in turn will remove the item from the list. The code is
certainly one correct way of doing it. The item will be deleted on the
gui thread.
> If yes this pops up a
> question should I not rely on Java-GC and dispose QObject's myself all
> the time to ensure a valid state?
No, you shouldn't. dispose() is an explicit delete and doesn't take into
account other potential pointers to the same data. For QObjects we have
a good chance of catching these things because QObjects have a deletion
notification on the C++ side, but for non-QObjects, like
QListWidgetItem, there could be scenarious where catching this is out of
our control.
> I see this from the point of a library developer - What would you
> suggest - should i dispose things explicitly when I don't need them any
> more? What's better from a performance point of view, I guess dispose,
> right because then the native resource is released immediately.
For images I always dispose immediately, because they are expensive. For
everything else, I normally rely on GC, because other objects are
usually small enough to not make a "big" difference...
---
But... Going back to the actual problem, the native crash... The problem
is caused by the fact that we, when we mapped the API for QListWidget,
did the same assumption you did, namely that removeItemWidget() removed
the item. Under this assumption we de-reffed the instance, allowing
garbage collection for the item even though it was still referenced by
the QListWidget. GC would kick in and delete the item and if the GUI
thread accessed the item at this time, this would have caused the crash.
If you either use takeItem() or explicit dispose() this will not happen.
Thank you a lot for finding this!
best regards,
Gunnar
More information about the Qt-jambi-interest
mailing list