c++qtqtcoreqvector

How to initialize QVector


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.


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.