2012-01-13 2 views
3

У меня проблемы с указателями и ссылками на парные.Использование указателей для доступа к элементам 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]; 

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

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

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

Есть ли у кого-нибудь идеи?

+1

Вы изменили (а) предмет? Это может привести к недействительности всех указателей. –

+0

Кроме того: если у вас есть небольшое постоянное число (четыре) именованных свойств, вы не должны использовать 'QVector' вообще. –

+1

Да ... Я сделал :(Вы имеете в виду, что изменение размера может перемещать вектор? ...Это имеет смысл, потому что ему нужны соседние ячейки памяти ... спасибо за эту идею ... Я изменю порядок кода и проведу результат: D – user1147533

ответ

4

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

+1

Правильнее сказать, что векторные итераторы - это просто указатели. Точнее, вы не можете построить итератор из указателя, но возможно обратное. – rubenvb

+1

@rubenvb: Нет, это не так. Указатели *** являются векторными итераторами ***, т. Е. Удовлетворяют rquiremnts концепции *** итератора ***. Но другие вещи могут служить итераторами. Например, в режиме отладки MSVC векторный итератор является классом, который проверяет границы –

+0

Да Я изменил размер вектора после присвоения ссылки !!! Спасибо! – user1147533

3

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

#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"; 
} 

Причины вещей происходит неправильно, являются:

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

Спасибо! У меня был неправильный порядок в моем коде – user1147533

1

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

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

2

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