Указатель на элемент вектора - в Windows - PullRequest
1 голос
/ 27 мая 2011

У меня есть следующие классы:

class A {};

class B { vector<A> vect; };

Я могу получить доступ к произвольному A, как это:

A a = b.vect[0];
// A *a_ptr = &a;

Но как я могу напрямую получить * a_ptr?

A *a_ptr = &b.vet[0];

компилируется и не выдает ошибок времени выполнения, но указывает на неправильную область памяти.

РЕДАКТИРОВАТЬ:

мой пример из реального мира: http://ideone.com/kP8NK

В то время как Ideone выдает ожидаемое «You are now at 0, 0, 0», компилятор MS VisualStudio выдает «You are now at 6624656, -33686019, -1414812757»

Ответы [ 4 ]

6 голосов
/ 27 мая 2011

Это не «неправильно», вы просто пропустили разницу.А именно:

A a = b.vect[0]; // Makes `a` a *copy* of the vector element
A *a_ptr = &a; // Address of the copy

A *a_ptr2 = &b.vect[0]; // Address of the element, not a copy

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

A& a = b.vect[0]; // Makes `a` a reference to the vector element
A *a_ptr = &a; // Address of the element, not a copy

Если вы все еще не получаете то, что ожидаете после наблюдения этой разницы,Вам нужно будет показать нам ваш точный пример, а также то, как вы определяете, каковы «правильные» и «неправильные» результаты.итераторы для элементов, когда size() == capacity(), потому что ему нужно выделить новый кусок памяти.Использование недействительного указателя (и др.) Приводит к неопределенному поведению, поэтому ваши результаты неизвестны.

Вместо этого вам следует хранить индексы и выполнять тривиальный поиск, чтобы получить фактический элемент.(Примечание vector остается упорядоченным, поэтому, даже если ваши комнаты могут перемещаться в памяти, их индекс одинаков.)

2 голосов
/ 27 мая 2011

A *a_ptr = &b.vect[0]; правильно.Если это не работает для вас, то вы делаете что-то еще или изменяете вектор после получения указателя.Векторные модификации обычно делают недействительными все указатели и итераторы в его элементах.

1 голос
/ 27 мая 2011

Ваша проблема в том, что вы изменяете вектор после переноса адреса на указатель. Здесь:

 World w;
    w.worldMap.push_back(Room(0, 0, 0)); // starting point
    Room *starting_room = &w.worldMap[0];

    w.worldMap.push_back(Room(1, 1, 5)); // treasure room
    Room treasure_room = w.worldMap[1];

Модификация контейнера делает недействительными все указатели / ссылки.

Если вы удалите эти строки:

    w.worldMap.push_back(Room(1, 1, 5)); // treasure room
    Room treasure_room = w.worldMap[1];

Отлично работает

1 голос
/ 27 мая 2011

У меня работает (после изменения vet на vect). См. http://ideone.com/V3tGS для доказательства.

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