Skip to content

Commit 480b395

Browse files
committed
Fix crash in QVector::reserve when reserving smaller size on a shared vector
We cannot call realloc with aalloc smaller than asize. Also include obvious optimisation: take the qMin computation out of the loop. Task-number: QTBUG-6416 Reviewed-by: Thiago
1 parent 537bff8 commit 480b395

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/corelib/tools/qvector.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ void QVector<T>::detach_helper()
324324
{ realloc(d->size, d->alloc); }
325325
template <typename T>
326326
void QVector<T>::reserve(int asize)
327-
{ if (asize > d->alloc || d->ref != 1) realloc(d->size, asize); d->capacity = 1; }
327+
{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; }
328328
template <typename T>
329329
void QVector<T>::resize(int asize)
330330
{ realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
@@ -441,6 +441,7 @@ void QVector<T>::free(Data *x)
441441
template <typename T>
442442
void QVector<T>::realloc(int asize, int aalloc)
443443
{
444+
Q_ASSERT(asize <= aalloc);
444445
T *pOld;
445446
T *pNew;
446447
union { QVectorData *d; Data *p; } x;
@@ -496,7 +497,8 @@ void QVector<T>::realloc(int asize, int aalloc)
496497
pOld = p->array + x.d->size;
497498
pNew = x.p->array + x.d->size;
498499
// copy objects from the old array into the new array
499-
while (x.d->size < qMin(asize, d->size)) {
500+
const int toMove = qMin(asize, d->size);
501+
while (x.d->size < toMove) {
500502
new (pNew++) T(*pOld++);
501503
x.d->size++;
502504
}

tests/auto/qvector/tst_qvector.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class tst_QVector : public QObject
5656

5757
private slots:
5858
void outOfMemory();
59+
void QTBUG6416_reserve();
5960
};
6061

6162
int fooCtor;
@@ -220,5 +221,18 @@ void tst_QVector::outOfMemory()
220221
}
221222
}
222223

224+
void tst_QVector::QTBUG6416_reserve()
225+
{
226+
fooCtor = 0;
227+
fooDtor = 0;
228+
{
229+
QVector<Foo> a;
230+
a.resize(2);
231+
QVector<Foo> b(a);
232+
b.reserve(1);
233+
}
234+
QCOMPARE(fooCtor, fooDtor);
235+
}
236+
223237
QTEST_APPLESS_MAIN(tst_QVector)
224238
#include "tst_qvector.moc"

0 commit comments

Comments
 (0)