'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).
-
[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?
-
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?
-
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.
-
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.