[Kde-perl] Memory fault when inserting QTableItem into QTable

Richard Dale Richard_Dale at tipitina.demon.co.uk
Sun Jul 11 14:04:14 CEST 2004


On Friday 09 July 2004 09:33, Oliver Kreuer wrote:
> I appended two example scripts with input files.
> Script "table_fault.pl" reproduces the memory fault whereas
> "table_ok.pl" contains a work around. The work around is not very
> pleasant so I'm still interested why this memory fault occurs.
> Due to bug #924345 the work around has to use takeItem insted of removeRow.
I've finally puzzled out what's going on. Inside PerlQt a QTableItem is 
actually an x_QTableItem and it has a destructor like this:

    ~x_QTableItem() { qt_Smoke->binding->deleted(314, (void*)this); }

In the qt_Smoke->binding->deleted() method, the mapping that PerlQt keeps 
between the C++ instance and the perl instance is removed. 

Then in the QTableItem destructor:

QTableItem::~QTableItem()
{
    if ( table() )
	table()->takeItem( this );
}

PerlQt overrides the takeItem() virtual method as part of its garbage 
collection tracking, and so when the perl version of takeItem() is called the 
recently deleted instance is found to not have a corresponding perl instance 
and another is created. Inside the perl takeItem() method the call 
'setAllocated( $_[0], 1 );' means that PerlQt owns this newly created 
instance owns the (already deleted) QTableItem and is responsible for 
deleting it.

sub Qt::Table::takeItem
{
    package Qt::_internal;
    delete ${ this()->{"hidden children"} } { sv_to_ptr($_[0]) };
    delete $_[0]->{"has been hidden"};
    setAllocated( $_[0], 1 );
    no strict 'refs';
    $Qt::AutoLoad::AUTOLOAD = 'Qt::Table::takeItem';
    my $autoload = " Qt::Table::_UTOLOAD";
    dontRecurse();
    $autoload->( $_[0] );
}

On garbage collection of the '$_[0]' passed to takeItem(), PerlQt attempts to 
delete an already deleted instance and there is a crash. Now I understand 
what's going on I can start to think of a fix..

This doesn't happen in qtruby because it doesn't currently override 
QTable->takeItem(), but it might in the future.

-- Richard


More information about the Kde-perl mailing list