Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Crash when comparingQModelIndexes



  • Hi,

    This forum has been invaluable helping me solve issues. I was wondering if someone can help me with this problem. I caught the failure in the debugger but don't understand why it cores. Th failure occurs intermittently.

    The core dump happens at this if statement.

    if((index1.data(0).toString().compare(index2.data(0).toString(), Qt::CaseInsensitive) == 0) &&
    index1.row() == index2.row() &&
    index1.parent().data(0).toString().compare(index2.parent().data(0).toString(), Qt::CaseInsensitive) == 0)

    If I check the indexes as invalid and passes why would it fail at the compare?
    Below is my method:

    bool MainWindow::compareQModelIndexes(QModelIndex index1, QModelIndex index2)
    {
    bool result = false;

    if(index1.isValid() == false && index2.isValid() == false)
        return result;  //this is false
    
    if((index1.data(0).toString().compare(index2.data(0).toString(), Qt::CaseInsensitive) == 0) &&
        index1.row() == index2.row() &&
        index1.parent().data(0).toString().compare(index2.parent().data(0).toString(), Qt::CaseInsensitive) == 0)
    {
        result = true;
    }
    else
    {
        result = false;
    }
    
    return result;
    

    }

    Thanks again.



  • For additional information, the calling process is like this. I use this to check if tree items are expanded or not so it remembers the last setting set by the user. There is a recursive function so I go through a full tree.

    //Iterate through the tree to get all the QModelIndexes
    void MainWindow::forEachQModelIndex(QModelIndex parent, int expanderIndex)
    {
        QModelIndex index;
    
        for(int row = 0; row < newDetailDataModel->rowCount(parent); row++)
        {
            index = newDetailDataModel->index(row, 0, parent);
    
            for(int i = 0; i < expanderQModelIndexList[expanderIndex].size(); i++)
            {
                //Check that the parent, row number, and attribute name matches between the saved QModelIndex to the recursive list.  If so keep expanded
                if(expanderQModelIndexList[expanderIndex][i].isValid() && index.isValid())
                {
                    //Attribute name, row number for attribute name, parent of attribute
                    if(MainWindow::compareQModelIndexes(expanderQModelIndexList[expanderIndex][i], index) == true)
                    {
                        ui->bottomTreeView->expand(index);
                        break;
                    }
                    else
                        ui->bottomTreeView->collapse(index);
                }
            }
    
            if(newDetailDataModel->hasChildren(index))
                forEachQModelIndex(index, expanderIndex);
        }
    }
    


  • @leinad said in Crash when comparingQModelIndexes:

    if(index1.isValid() == false && index2.isValid() == false)

    This checks for both being invalid. The crash can happen if index1 is valid and index2 is not or viceversa.



  • @VRonin said in Crash when comparingQModelIndexes:

    This checks for both being invalid.

    Well, I tied this earlier and then again now but still crashes in the same place.

    if(index1.isValid() == false || index2.isValid() == false)
    return result; //this is false



  • can you post the stack trace of the crash?
    Are you sure it's a sigsev or can it be stack overflow?



  • I can try to show the stack trace. I think I figured out the problem which was elsewhere that seems to correct the crash but I'm still curious as why "isValid" lets it through. Is it possible to have a valid isValid return value but the index itself may be bad or expired? For example we reference an index which represent some row in a table but then remove that row. I would think the index should be nullified when checking if valid.


  • Lifetime Qt Champion

    @leinad said in Crash when comparingQModelIndexes:

    I would think the index should be nullified when checking if valid.

    Why?
    "Note: Model indexes should be used immediately and then discarded. You should not rely on indexes to remain valid after calling model functions that change the structure of the model or delete items. If you need to keep a model index over time use a QPersistentModelIndex."



  • @Christian-Ehrlicher said in Crash when comparingQModelIndexes:

    QPersistentModelIndex

    Thanks. If I don't use QPersistentModelIndex should index.isvalid() detect for a bad index? I'm just trying to figure out what is the point of using isvalid() if it doesn't find protect for failure?


  • Lifetime Qt Champion

    @leinad said in Crash when comparingQModelIndexes:

    should index.isvalid() detect for a bad index?

    No, see the documentation


Log in to reply