'index out of range' When Using QList



  • Hi, I'm working on a code program called Nova, and I've run into an error when launching the program on Ubuntu (or Linux in general I guess)

    In the terminal, after compiling, if I type './Nova', the following error comes up:

    ASSERT failure in QList<T>::at: "index out of range", file ../../../qtsdk-2010.05/qt/include/QtCore/qlist.h, line 455

    If I try running the program from within Qt Creator, it crashes.

    The program source can be found at http://github.org/NovaEdit/Nova if you need it (It's too large to post all of it here).



  • It should not be hard for you to find where on your code you are trying to get an element from a QList with an invalid index. Just set a bunch of breakpoints and start the application on debug mode.



  • Alright, let me test and see how that works.



  • I suppose, if you run that code in Debug mode you will see that line, where assert is called.



  • Okay, when stepping through the program, as soon as the .exec() function is run in main.cpp, Qt Creator crashes.



  • [quote author="IrQX" date="1291164317"]I suppose, if you run that code in Debug mode you will see that line, where assert is called.[/quote]

    Could the problem be, because I have three global QLists, and in one function, I do a .insert(index (which is 0), value); into all three QLists.

    Could that be causing the problem?



  • Also, I stepped into it further, it seems as though the entire thing crashes when the UI is drawn.



  • I've narrowed it down enough to where it happens here:

    @
    int returnCode = eventLoop.exec();
    @

    Which is in qcoreapplication.cpp within the Qt source files. Line 1009.



  • when program crashes you also could look call stack, which will help you. Not sure, that using global (you means static?) objects is good from modelling point. BTW if your's QList is initiated and you insert also initiated object in list i don't see problem here.

    Can you show logs?



  • Set breakpoint in file ../../../qtsdk-2010.05/qt/include/QtCore/qlist.h, line 455 and run program



  • When I run into these kinds of Qt asserts, I usually do this to make my debugging life easier:

    @//in file main.cpp
    void crashingMessageHandler(QtMsgType type, const char *msg)
    {
    switch (type) {
    case QtDebugMsg:
    fprintf(stderr, "Debug: %s\n", msg);
    break;
    case QtWarningMsg:
    fprintf(stderr, "Warning: %s\n", msg);
    break;
    case QtCriticalMsg:
    fprintf(stderr, "Critical: %s\n", msg);
    break;
    case QtFatalMsg:
    fprintf(stderr, "Fatal: %s\n", msg);
    __asm("int3");
    abort();
    }
    }

    int main(int argc, char ** argv)
    {
    qInstallMsgHandler(crashingMessageHandler);
    //rest of your main function
    }
    @

    This will cause a crash when an assert happens (caused by the call on line 16). Now you can use the debugger in Qt Creator to get a call stack. It will be a bit deeper than ideal, but at least you can find the offending call to QList where your index is off.



  • [quote author="sammarks" date="1291166368"]I've narrowed it down enough to where it happens here:

    @
    int returnCode = eventLoop.exec();
    @

    Which is in qcoreapplication.cpp within the Qt source files. Line 1009.[/quote] This is the normal behavior of any runtime error.

    I think you should check your calls to QList::at again. Inserting will not cause this sort of assertation failure.



  • BTW: Was it really a good idea to ban exceptions from Qt, and using assertations instead?



  • Line 90 in mainwindow.cpp seem suspicious to me:

    Line 89:
    @
    void MainWindow::TextChanged() {
    if (saves.at(ui->tabs->currentIndex() == 1)) {
    @



  • Andre, interesting debugging practice :)

    Wolf P., yes, looks likes someone misplaced ')'.



  • Sorry for the extremely long delay in replying, but I discovered a solution to the problem if anyone's interested.

    I discovered that it was because I was using .at() instead of .value() when getting values from the QList. That resolved the problem for me.



  • So, that means that you are still trying to read values that are not actually in your list, only now you don't notice because QList returns a default constructed value for you. If you do that by design, then fine, but that does not seem to be the case. I suggest you try to track the actual cause of the problem, instead of just making sure it doesn't trigger a crash.



  • [quote author="Andre" date="1302680125"]So, that means that you are still trying to read values that are not actually in your list, only now you don't notice because QList returns a default constructed value for you. If you do that by design, then fine, but that does not seem to be the case. I suggest you try to track the actual cause of the problem, instead of just making sure it doesn't trigger a crash. [/quote]

    If I remember correctly, the actual cause of the problem wasn't because something was out of range, as it returned a legitimate value when the .value() was called, but the simple fact that I was using .at() didn't build correctly on the Linux platform for some reason.



  • .at() works also on linux.

    you could use something like this to check it:

    @
    foo(int index)
    {
    Q_ASSERT(0 <= index);
    Q_ASSERT(index < list.size());
    return list.at(index);
    }
    @

    if one of the assert fails, you are out of bounds.
    and that is exacltly what at(...) does:

    @
    inline const T &QList<T>::at(int i) const
    {
    Q_ASSERT_X( (i >= 0) &&
    (i < p.size()),
    "QList<T>::at", "index out of range");
    return reinterpret_cast<Node *>(p.at(i))->t();
    }
    @

    So I'm 99,9 % sure that the bug is in your code. Check it.



  • [quote author="sammarks" date="1302724779"]
    [quote author="Andre" date="1302680125"]So, that means that you are still trying to read values that are not actually in your list, only now you don't notice because QList returns a default constructed value for you. If you do that by design, then fine, but that does not seem to be the case. I suggest you try to track the actual cause of the problem, instead of just making sure it doesn't trigger a crash. [/quote]

    If I remember correctly, the actual cause of the problem wasn't because something was out of range, as it returned a legitimate value when the .value() was called, but the simple fact that I was using .at() didn't build correctly on the Linux platform for some reason.[/quote]

    QList::at() works just as well on linux (and all other supported platforms) as it does on Mac. Like I said (and the documentation for QList says; don't take my word for it): QList returns a default constructed value for you if the index you pass to it is out of bounds. So, my bet is that your code is actually trying to access an out of bounds value, and that Qt is behaving just the way it should.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.