Game Development Community

Error in t2dSceneObject::detachGui() causes Access Violation

by Richard McKinney · in Torque Game Builder · 04/04/2007 (3:41 pm) · 1 replies

The comment was correct at least! If you use t2dSceneObject::attachGui() and detachGui(), when the SceneWindow gets destroyed, it's got two references to the scene object instead of zero, causing an access violation when SimObject::processDeleteNotifies() gets called on it (when the memory manager is disabled, and who knows when it isn't). Very simple two character fix for this:

In t2dSceneObject::detachGui(), around line 6118, we have:
// Unregister Gui Control Reference.
    if ( mpAttachedGuiSceneWindow )
    {
        mpAttachedGuiSceneWindow->registerReference( (SimObject**)&mpAttachedGuiSceneWindow );
        mpAttachedGuiSceneWindow = NULL;
    }

and this should be changed to :

// Unregister Gui Control Reference.
    if ( mpAttachedGuiSceneWindow )
    {
        mpAttachedGuiSceneWindow->[b]un[/b]registerReference( (SimObject**)&mpAttachedGuiSceneWindow );
        mpAttachedGuiSceneWindow = NULL;
    }

#1
07/31/2007 (8:59 am)
So it looked like in the release notes for 1.5 that this was fixed. I checked up on it and the code is exactly the same except now it has a comment from Neo Bindell saying "// Changed to UNregisterReference was registerReference which would crash later", but that's on the line that was already calling unregisterReference(), not the one that below it that should have been changed :).

Here's the code in 1.1.3:
void t2dSceneObject::detachGui( void )
{
    // Unregister Gui Control Reference.
    if ( mpAttachedGui )
    {
        mpAttachedGui->unregisterReference( (SimObject**)&mpAttachedGui );
        mpAttachedGui = NULL;
    }

    // Unregister Gui Control Reference.
    if ( mpAttachedGuiSceneWindow )
    {
        mpAttachedGuiSceneWindow->registerReference( (SimObject**)&mpAttachedGuiSceneWindow );
        mpAttachedGuiSceneWindow = NULL;
    }
}

and the code in 1.5.1 which is functionally the same as 1.1.3:
void t2dSceneObject::detachGui( void )
{
    // Unregister Gui Control Reference.
    if ( mpAttachedGui )
    {
       // [neo, 5/7/2007 - #2997]
       // Changed to UNregisterReference was registerReference which would crash later
       mpAttachedGui->unregisterReference( (SimObject**)&mpAttachedGui );
        mpAttachedGui = NULL;
    }

    // Unregister Gui Control Reference.
    if ( mpAttachedGuiSceneWindow )
    {
        mpAttachedGuiSceneWindow->registerReference( (SimObject**)&mpAttachedGuiSceneWindow );

        mpAttachedGuiSceneWindow = NULL;
    }
}

and what the code should look like:
void t2dSceneObject::detachGui( void )
{
    // Unregister Gui Control Reference.
    if ( mpAttachedGui )
    {
       mpAttachedGui->unregisterReference( (SimObject**)&mpAttachedGui );
        mpAttachedGui = NULL;
    }

    // Unregister Gui Control Reference.
    if ( mpAttachedGuiSceneWindow )
    {
       // [neo, 5/7/2007 - #2997]
       // Changed to UNregisterReference was registerReference which would crash later
        mpAttachedGuiSceneWindow->unregisterReference( (SimObject**)&mpAttachedGuiSceneWindow );
        mpAttachedGuiSceneWindow = NULL;
    }
}