虽然其他答案在解释问题方面做出了有用的尝试,但它们都没有真正回答问题或没有抓住重点。感谢大家帮我追查问题。
正如 Ali Mofrad 所提到的,当 QList 未能在我的 QList::append(MyObject*) 调用中分配额外空间时,引发的错误是 std::bad_alloc 错误。这是 Qt 源代码中发生这种情况的地方:
qlist.cpp: line 62:
static int grow(int size) //size = 268435456
{
//this is the problem line
volatile int x = qAllocMore(size * sizeof(void *), QListData::DataHeaderSize) / sizeof(void *);
return x; //x = -2147483648
}
qlist.cpp: line 231:
void **QListData::append(int n) //n = 1
{
Q_ASSERT(d->ref == 1);
int e = d->end;
if (e + n > d->alloc) {
int b = d->begin;
if (b - n >= 2 * d->alloc / 3) {
//...
} else {
realloc(grow(d->alloc + n)); //<-- grow() is called here
}
}
d->end = e + n;
return d->array + e;
}
在grow() 中,请求的新大小 (268,435,456) 乘以 sizeof(void*) (8) 以计算新内存块的大小以适应不断增长的 QList。问题是,如果是无符号 int32,则 268435456*8 等于 +2,147,483,648,对于有符号 int32,则等于 -2,147,483,648,这是在我的操作系统上从 grow() 返回的内容。因此,当在QListData::realloc(int) 中调用 std::realloc() 时,我们正试图增长到负大小。
正如ddriver 建议的那样,这里的解决方法是使用QList::reserve() 预先分配空间,防止我的QList 不得不增长。
简而言之,QList 的最大大小为 2^28-1 个项目除非您预先分配,在这种情况下,最大大小确实是预期的 2^31-1。
更新(2020 年 1 月):Qt 5.5 中的This appears to have changed,这样 2^28-1 现在是 QList 和 QVector 允许的最大大小,无论您是否提前预订。可惜了。