Phl*_*ous 5 c++ qt qt4 qlist qtcore
有没有人遇到过QList的最大尺寸?
我有一个指向我的对象的指针的QList,并且发现当它到达268,435,455项(它正好是28位)时它会默默地抛出一个错误.我原以为它至少有一个31位的最大大小(减去一位因为size()返回有符号整数),或者我的64位计算机上最大大小为63位,但事实并非如此.我通过QList<void*> mylist; mylist.append(0);在计数循环中执行来在最小的例子中证实了这一点.
要重申这个问题,QList的实际最大大小是多少?如果它实际上不是2 ^ 32-1那么为什么呢?有解决方法吗?
我正在为MSVC2010运行Qt 4.8.5的Windows 64位版本.
虽然其他答案在解释问题上做出了有用的尝试,但没有一个真正回答了问题或错过了要点。感谢大家帮助我找出问题所在。
正如 Ali Mofrad 提到的,std::bad_alloc当 QList 无法在我的QList::append(MyObject*)调用中分配额外空间时,抛出的错误是一个错误。下面是 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;
}
Run Code Online (Sandbox Code Playgroud)
在 中grow(),请求的新大小 (268,435,456) 乘以sizeof(void*)(8) 来计算新内存块的大小,以适应不断增长的 QList。问题是,如果是 unsigned int32,则 268435456*8 等于 +2,147,483,648;对于有符号 int32,则等于 -2,147,483,648,这是从grow()我的操作系统返回的值。因此,当在 中调用 std::realloc() 时QListData::realloc(int),我们试图增长到负大小。
正如建议的,这里的解决方法ddriver是使用QList::reserve()预分配空间,防止我的 QList 增长。
简而言之,QList 的最大大小为 2^28-1 项,除非您预先分配,在这种情况下,最大大小实际上是 2^31-1 正如预期的那样。
更新(2020 年 1 月):这似乎在 Qt 5.5 中发生了变化,因此 2^28-1 现在是 QList 和 QVector 允许的最大大小,无论您是否提前预订。丢人现眼。