C ++ std :: vector segfault при использовании erase (), хорошо при использовании pop_back () с g ++ - PullRequest
1 голос
/ 13 января 2011

Пожалуйста, обратите внимание на следующий код:

vector<int> myVector;
myVector.push_back(10);
myVector.erase(myVector.end());

Этот код компилируется и отлично работает в Windows (VisualStudio), но приводит к segfault в Linux при компиляции с g ++. Замена стирания на pop_back решает проблему в Linux.

Кто-нибудь знает, почему поведение на двух платформах различается и какое поведение считать правильным.

Заранее спасибо!

Ответы [ 4 ]

9 голосов
/ 13 января 2011

end() обычно возвращает недопустимую позицию в массиве (одну за концом).

pop_back() удаляет последний элемент в векторе.

Если вы хотите стереть,Вы должны сделать erase(end() - 1); здесь end() - 1 возвращает итератор для последнего элемента.

erase(end()) должен вызвать UB - что я считаю правильным ...

РЕДАКТИРОВАТЬ: как Мартинуказал перед тем, как вызвать erase(end() - 1), убедитесь, что вектор не пустой!

0 голосов
/ 13 января 2011

myVector.end() дает вам итератор справа после последнего элемента в вашем векторе.Поскольку там ничего нет, вызывать стирание не имеет особого смысла.

Мне любопытно узнать, что именно делает Visual Studio, когда вы вызываете это.Запустите несколько тестов, чтобы увидеть, действительно ли он стирает 10 из вашего вектора или просто изящно игнорирует ваш неверный запрос.

0 голосов
/ 13 января 2011

myVector.end() не указывает на последний элемент вектора.Он указывает мимо последнего элемента вектора.Я не уверен, однако, если это квалифицируется как неопределенное поведение (если это так, то разумно, что Windows и Linux ведут себя по-разному).

0 голосов
/ 13 января 2011

end() указывает на никуда, это за пределами конца.

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