Использование указателей для доступа к элементам QVector

У меня проблемы с указателями и ссылками на двойники.

Я хочу получить доступ к элементам в QVector по именам. Вектор содержит двойники:

QVector<double> properties;
properties.append(28.0);
properties.append(1.0);
properties.append(44.0);
properties.append(0.001);

Теперь я создаю указатели на двойники:

double* Amplitude;
double* Frequency;
double* PhaseDifference;
double* Stepsize;

Эти указатели должны обеспечивать доступ к элементам моего вектора:

Amplitude = &properties[0];
Frequency = &properties[1];
PhaseDifference = &properties[2];
Stepsize = &properties[3];

На мой взгляд, разыменование этих указателей должно дать мне правильные значения, но это не так. В этом случае я получил нули для первых двух указателей, а третий и четвертый были правильными.

Я попытался использовать больше записей в векторе, и в результате только два последних имели правильные значения. Что там не так?

Я создаю и печатаю значения в конструкторе. Печать вектора дает правильные значения!

У кого-нибудь есть идея?


person user1147533    schedule 13.01.2012    source источник
comment
Вы изменили вектор? Это может сделать недействительными все указатели.   -  person Šimon Tóth    schedule 13.01.2012
comment
Кроме того: если у вас есть небольшое постоянное количество (четыре) именованных свойств, вам вообще не следует использовать QVector.   -  person Fred Foo    schedule 13.01.2012
comment
Да... Я сделал :( Вы имеете в виду, что изменение размера может сдвинуть вектор?? ... Это имеет смысл, потому что ему нужны соседние ячейки памяти... спасибо за эту идею... Я изменю порядок кода и проверить результат :D   -  person user1147533    schedule 13.01.2012
comment
О да... в этом была проблема!! У меня был неправильный порядок в моем коде. Изменение размера вектора делало ссылки недействительными. Большое спасибо ;)   -  person user1147533    schedule 13.01.2012
comment
stackoverflow.com/questions/6438086/iterator-invalidation-rules   -  person Lightness Races in Orbit    schedule 13.01.2012


Ответы (4)


Ваши именованные указатели на самом деле являются итераторами. Итераторы могут быть аннулированы. Например, всякий раз, когда вы изменяете размер вектора или вставляете в него что-либо и т. д. Найдите точные правила аннулирования итератора для вашего конкретного типа вектора, в данном случае QVector, и посмотрите, выполняли ли вы какие-либо из этих операций аннулирования итератора до этого. к печати. Между прочим, разыменование недействительного итератора может привести к неопределенному поведению.

person Armen Tsirunyan    schedule 13.01.2012
comment
правильнее было бы сказать, что векторные итераторы - это просто указатели. Точнее, вы не можете построить итератор из указателя, но возможно обратное. - person rubenvb; 13.01.2012
comment
@rubenvb: Нет, это не так. Указатели являются векторными итераторами, т. е. удовлетворяют требованиям концепции итераторов. Но другие вещи также могут служить итераторами. Например, в режиме отладки MSVC векторный итератор — это класс, который проверяет границы - person Armen Tsirunyan; 13.01.2012
comment
@user1147533: Пожалуйста. Если мой ответ решил вашу проблему, вы должны принять его. - person Armen Tsirunyan; 13.01.2012

Вы должны делать что-то не так. Это работает:

#include <QVector>
#include <QDebug>

int main()
{
    QVector<double> v;
    v.append(2.0);
    v.append(18.4);

    double* val1 = &v[0];
    double* val2 = &v[1];

    qDebug() << *val1 << "\n" << *val2 << "\n";
}

Причинами того, что что-то идет не так, являются:

  • вектор перераспределяется (изменяется размер + перемещается в другую позицию в памяти)
  • элементы удаляются из вектора.
  • вывод сделан неправильно, или вы печатаете адреса памяти вместо значений.
person rubenvb    schedule 13.01.2012

Вы должны установить размер вектора при их инициализации. Все будет хорошо, пока вы их не измените (push/pop), после чего значения в ваших указателях станут неопределенными.

person gingray    schedule 13.01.2012

Существует вероятность того, что ваши указатели могут стать недействительными в период между тем, как вы их получили, и временем, когда вы их фактически использовали.

Это может произойти, если изменить размер QArray (путем добавления большего количества элементов, чем он может вместить в данный момент).

person Tony the Pony    schedule 13.01.2012