Question

I am new to c++ and Qt and I am trying to initialize a QVector, which is a class member in a class initialization list like:

MyClass::MyClass(QWidget *parent) : QMainWindow(parent) , myVector(QVector<double>(100))

I was expecting the QVector to have already 100 indexes alocated, but when I try to read myVector[0] I get an assertion error saying "Unhandled exception at 0x0143bf77 in test.exe: 0xC0000005: Access violation reading location 0x00000004." and the program stops at this line of Qt:

inline T &QVector<T>::operator[](int i)
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
  return data()[i]; }

Which I believe shows that I am trying to access members that arent allocated yet, so I guess I am not using the initialization list properly. I could make it a pointer and make a new QVector(100) in the constructor but I want to learn what's wrong and how may I make it correct.

Was it helpful?

Solution

You are probably doing something wrong unshown because the following code works fine for me, and it should by design. Note that for the first element, you could use the convenience first method.

main.cpp

#include <QVector>
#include <QDebug>

int main()
{
    QVector<double> myVector(QVector<double>(100));
    qDebug() << "TEST FIRST:" << myVector.first();
    return 0;
}

main.pro

TEMPLATE = app
TARGET = main
SOURCES += main.cpp

Output

TEST FIRST: 0

As I noted in the comment, you could use the reserve method.

void QVector::reserve(int size)

Attempts to allocate memory for at least size elements. If you know in advance how large the vector will be, you can call this function, and if you call resize() often you are likely to get better performance. If size is an underestimate, the worst that will happen is that the QVector will be a bit slower.

The sole purpose of this function is to provide a means of fine tuning QVector's memory usage. In general, you will rarely ever need to call this function. If you want to change the size of the vector, call resize().

So, you would be writing something like this:

MyClass::MyClass(QWidget *parent)
    : QMainWindow(parent)
{
    myVector.reserve(100);
}

However, as I also noted later in the comment, the simple constructor should also work like:

MyClass::MyClass(QWidget *parent)
    : QMainWindow(parent)
    , myVector(100)
{
}

What you are doing is invoking the copy constructor (although for an implicitly shared class), so it may be negligibly slower. It is at least more code than you need.

OTHER TIPS

Try something like this :

QVector<double> * vect = new QVector<double>;
vect->reserve(100);

void QVector::reserve(int size)

Attempts to allocate memory for at least size elements. If you know in advance how large the vector will be, you can call this function, and if you call resize() often you are likely to get better performance. If size is an underestimate, the worst that will happen is that the QVector will be a bit slower. The sole purpose of this function is to provide a means of fine tuning QVector's memory usage. In general, you will rarely ever need to call this function. If you want to change the size of the vector, call resize().

But this will only reserve the memory, if you want to browse it, use fill(<double>)

QVector<double> * vect = new QVector<double>;
vect->resize(100);

void QVector::resize(int size) Sets the size of the vector to size. If size is greater than the current size, elements are added to the end; the new elements are initialized with a default-constructed value. If size is less than the current size, elements are removed from the end.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top