Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 450
Michel Feinstein Avatar asked Jan 05 '14 12:01

Michel Feinstein


2 Answers

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>)

like image 194
Thomas Ayoub Avatar answered Oct 31 '22 17:10

Thomas Ayoub


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.

like image 20
lpapp Avatar answered Oct 31 '22 18:10

lpapp