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

У меня есть std::vector какого-то класса, и в моей программе есть какие-то указатели на несколько элементов в векторе, проблема в том, что когда я удаляю один элемент, например первый элемент, все указатели неверны, это пример код:

vector<int> numbers;
numbers.push_back(100);
numbers.push_back(200);
numbers.push_back(300);

int *pNum = & numbers[1]; // pNum pointer to 200

numbers.erase(numbers.begin()); // now pNum pointer to 300

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


person user1544067    schedule 04.07.2013    source источник
comment
сделайте копию нужных данных.   -  person andre    schedule 04.07.2013
comment
Я хочу, чтобы pNum всегда был указателем на ячейку, содержащую значение 200.   -  person user1544067    schedule 04.07.2013
comment
создает функцию, которая удаляет данные и обновляет указатель? Также что произойдет, если кто-то удалит значение 200?   -  person andre    schedule 04.07.2013
comment
вероятно, немного излишне, почему бы не использовать указатель? итак, ваш вектор выглядит так: std::vector<std::unique_ptr<int>>, тогда вас не заденет релокация...   -  person Nim    schedule 04.07.2013
comment
@nim, я должен использовать shared_ptr, потому что 200, я думаю, делится между pNum и числами.   -  person Zhen    schedule 04.07.2013


Ответы (2)


Вы можете сохранять указатели в векторе. Таким образом, вы отделяете данные от вектора, а ваша ссылка указывает на реальные данные.

vector<int*> numbers;

numbers.push_back(new int(100));
numbers.push_back(new int(200));
numbers.push_back(new int(300));

int * pNum  = numbers[1];

// memory leak!!!
numbers.erase( numbers.begin() );

cout << *pNum << endl;

Безопасно, если вы используете С++ 11, ставить shared_ptrs вместо необработанных указателей.

person Zhen    schedule 04.07.2013

Вы можете использовать структуру на основе узлов, такую ​​как std::list. Это гарантирует, что итераторы, отличные от итераторов для стертых элементов, останутся действительными.

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

person juanchopanza    schedule 04.07.2013
comment
Да, только std::list занимает больше памяти - person user1544067; 04.07.2013