#c #vector #stl #reverse-iterator
Вопрос:
Я использую reverse_iterator для поиска своего вектора и использую pop_back для стирания элементов.Но это вызывает некоторую ошибку в режиме отладки. Мой код таков:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Student{
string name;
int score;
};
int main()
{
vector<Student> testVec;
testVec.push_back(Student{ "Lilei",50 });
testVec.push_back(Student{ "YangFeifei",80 });
testVec.push_back(Student{ "WuMing",80 });
for (auto it = testVec.rbegin(); it != testVec.rend(); it){
if (it == testVec.rbegin()) continue;
while (it != testVec.rbegin()) {
std::cout << amp;(*testVec.rbegin()) << ", ";
std::cout << amp;(*it) << std::endl;
testVec.pop_back();
std::cout << amp;(*testVec.rbegin()) << ", ";
std::cout << amp;(*it) << std::endl; // where error occur!
}
}
std::cout << "Hello World!n";
}
Комментарии:
1. Существует большая вероятность того, что, если отладочная сборка что-то поймает, что-то не так. В сборке выпуска, похоже, все работает, но во многих случаях вы будете менять память там, где не хотите, и вы узнаете об этом только позже. К тому времени это будет сложнее отладить… так что отнеситесь к своему предупреждению об отладке сборки серьезно!
2. Пожалуйста, укажите ошибки в вопросе, когда вы их получите.
Ответ №1:
В этой документации std::vector<>::pop_back()
говорится, что:
Итераторы и ссылки на последний элемент, а также итератор end() становятся недействительными.
Следовательно, ваш it
итератор недействителен после вашего вызова pop_back()
. Поведение разыменования этого итератора не определено, поэтому поведение вашей программы будет непредсказуемым.
В вашем конкретном случае возможно, что в отладочных сборках существуют некоторые дополнительные методы для среды выполнения, позволяющие определить, что вы допустили ошибку, но эти проверки могут быть дорогостоящими для производительности, поэтому могут не включаться в сборку выпуска. В любом случае, такое поведение не гарантируется. Решение состоит в том, чтобы не использовать it
его после вызова pop_back()
.
Комментарии:
1. Я думал, что мой
it
итератор не дошел до последнего элемента перед вызовомpop_back()
. И я проверил несколько разных случаев. Случай,it
когда итератор указывает на второй элемент снизу,pop_back()
и случай, когда итератор указывает на третий элемент снизу. И результат показывает, что в первом случае возникает ошибка, но не во втором случае. Таким образом, оба итератора указывают на последний элемент до и после вызоваpop_back()
, будут недействительными. Верно?