I am writing a simple (for now) IRC client in QML, using the Communi library and some C++ backend code. The main output page of my client consists of a TabBarLayout/TabGroup combo, with dynamically created TabButtons - one for the server output and one for each of the IRC channels the user joins. TabButtons are identified using the text: property, which contains the name of the channel, or "Server" for the server's output tab. The tab: property of the TabButton is and OutputFlickable item, basically a TextEdit element in a Flickable with a couple of extra properties. The server tab is created in the main page's onCompleted method, and the channel tabs are created as needed when an IRC channel is successfully joined, and destroyed when the channel is left.

I have created two JS functions to create and destroy the TabButton and output page, as documented in the QML documentation:

Code:
// Create a tab for channel
    function createTab(channel)
    {
        // Create an OutputFlickable item, attach it to the TabGroup
        var pageFactory = Qt.createComponent("OutputFlickable.qml")
        var page = pageFactory.createObject(outputTabGroup)

        // Create the TabButton and attach it to the TabBarLayout.
        var button = Qt.createQmlObject("import QtQuick 1.1; import com.nokia.symbian 1.1; TabButton{}", outputTabBarLayout)
        //console.log("Creating tab %s",channel)
        
        // set the TabButton text and the OutputFlickable text property
        button.text = channel
        page.channel = channel
        page.outputText.text = ""
        button.tab = page
        outputTabGroup.currentTab = page
    }
Code:
// Remove the tab with text property channel fro hte TabBarLayout
    function closeTab(channel)
    {
        // Find the correct TabButton. findButton() returns undefined if 
        // no button is found. 
        var button = findButton(channel)
        if (button)
        {
            console.log("Closing tab ", channel)
            // If the channel isn't the server, leave the channel
            if (channel !== Session.host)
                Session.partChannel(channel)
            
            // Destroy the OutputFlickable (button.tab) and the TabButton
            button.tab.destroy()
            button.destroy()
        }

    }
As you can see, fairly standard stuff, and indeed it seems to work fine. Tabs open and close on joining and leaving channels, and output is correctly steered to the relevant tab. On closing the app, things go horribly wrong:

  • If the only tab ever created is the Server tab, the client exits fine.
  • If there has been a channel tab open, but it's now closed, the app crashes on exit with the following message:
    The program has unexpectedly finished.
    C:\QtProjects\QMLIrc\debug\QMLIrc.exe exited with code -1073741819
  • If there is more than one tab open on closing, the app crashes with this message:
    ASSERT: "d" in file ..\..\include/QtCore/../../../../../../ndk_buildrepos/qt-simulator/src/corelib/tools/qscopedpointer.h, line 112
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.
    QDeclarativeExpression: Attempted to evaluate an expression in an invalid context


If I alter my program so all IRC channel output goes through the Server tab, the program exits fine. I use the createTab() function above to create all the tabs, including the Server tab. The only difference is that the Server tab is created in the main page's Component.onCompleted() function, and the channel tabs in the code which handles the channel JOIN message from the IRC server.
Any ideas?
If you want to look at all of the code, the GitHub repo is here: https://github.com/marknotgeorge/QMLIrc