web-dev-qa-db-ja.com

QVectorを初期化する方法

私はc ++とQtを初めて使用し、次のようなクラス初期化リストのクラスメンバーであるQVectorを初期化しようとしています。

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

QVectorにはすでに100個のインデックスが割り当てられていると思っていましたが、_myVector[0]_を読み取ろうとすると、「test.exeの0x0143bf77で未処理の例外:0xC0000005:アクセス違反の読み取り場所0x00000004」というアサーションエラーが発生します。プログラムは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]; }
_

これは、まだ割り当てられていないメンバーにアクセスしようとしていることを示していると思います。そのため、初期化リストを適切に使用していないと思います。ポインターにしてコンストラクターでnew QVector(100)を作成することもできますが、何が問題で、どのように修正すればよいかを知りたいと思います。

10
mFeinstein

次のコードは私にとっては問題なく機能するため、表示されていない何か間違ったことをしている可能性があります。 設計によるはずです 。最初の要素には、便利な 最初のメソッド を使用できることに注意してください。

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

出力

TEST FIRST: 0

コメントで述べたように、 予約方法 を使用できます。

void QVector :: reserved(int size)

少なくともサイズの要素にメモリを割り当てようとします。ベクトルの大きさが事前にわかっている場合は、この関数を呼び出すことができます。resize()を頻繁に呼び出すと、パフォーマンスが向上する可能性があります。サイズが過小評価されている場合、発生する最悪の事態は、QVectorが少し遅くなることです。

この関数の唯一の目的は、QVectorのメモリ使用量を微調整する手段を提供することです。一般に、この関数を呼び出す必要はほとんどありません。ベクトルのサイズを変更する場合は、resize()を呼び出します。

だから、あなたはこのようなものを書くでしょう:

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

ただし、コメントの後半でも述べたように、単純なコンストラクターも次のように機能するはずです。

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

あなたがしていることは、コピーコンストラクターを呼び出すことです(暗黙的に共有されたクラスの場合ですが)ので、無視できるほど遅くなる可能性があります。少なくとも必要以上のコードです。

11
lpapp

このようなものを試してください:

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

void QVector :: reserved(int size)

少なくともサイズの要素にメモリを割り当てようとします。ベクトルの大きさが事前にわかっている場合は、この関数を呼び出すことができます。resize()を頻繁に呼び出すと、パフォーマンスが向上する可能性があります。サイズが過小評価されている場合、発生する最悪の事態は、QVectorが少し遅くなることです。この関数の唯一の目的は、QVectorのメモリ使用量を微調整する手段を提供することです。一般に、この関数を呼び出す必要はほとんどありません。ベクトルのサイズを変更する場合は、resize()。を呼び出します。

ただし、これはメモリを予約するだけです。参照する場合は、fill(<double>)を使用してください。

1
Thomas Ayoub