[英]Expression: vector erase iterator outside range when using vector.erase()
I am new to C++ and was trying to write a program that takes the lowest and the highest numbers in a vector, takes them away from the vector and proceeds to calculate an average with the rest of the numbers.我是 C++ 新手,并试图编写一个程序,该程序采用向量中的最低和最高数字,将它们从向量中取出并继续计算其余数字的平均值。
Now while I understand that I could do it after the numbers have been entered, I wanted to challenge myself and carry out these checks as the numbers were entered one by one.现在,虽然我知道我可以在输入数字后做到这一点,但我想挑战自己并在数字一个一个输入时进行这些检查。 I was looking around but I couldn't find another person with the exact issue I am having (since I am using vector.end() - 1).我环顾四周,但找不到与我遇到的确切问题有关的另一个人(因为我使用的是 vector.end() - 1)。
Below is my code and the error that it is giving me.下面是我的代码和它给我的错误。 Any guidance is much appreciated.非常感谢任何指导。
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <limits.h>
using namespace std;
typedef vector<int>::iterator iter;
int main() {
cout << "Please enter the series of scores: \n";
// Read numbers from the standard input
// and store them in a vector
vector<int> scoreVector;
int x = 0;
int count = 0;
// Assign the lowest possible value to the maximum possible integer so that any value entered initially will be lower that INT_MAX
int lowestValue = INT_MAX;
int highestValue = 0;
iter lowestValueIndex;
iter highestValueIndex;
// Every time a number is entered, the program checks to see if it meets the criteria for the lowest or highest number entered so far
while (cin >> x) {
scoreVector.push_back(x);
if (x > highestValue) {
highestValueIndex = scoreVector.end() - 1;
highestValue = x;
}
if (x < lowestValue) {
lowestValueIndex = scoreVector.end() - 1;
lowestValue = x;
}
}
// Calculate the vector size
auto n = scoreVector.size();
if (n > 2) {
cout << "\nThe lowest value is:" << lowestValue << "\nThe highest value is: " << highestValue << ". These values have been taken out." << '\n';
// Remove the two values from the vector
scoreVector.erase(lowestValueIndex);
scoreVector.erase(highestValueIndex);
// Calculate the average
auto average = accumulate(scoreVector.begin(), scoreVector.end(), 0.0) / n;
cout << "\naverage = " << average << '\n';
}
return 0;
}
According to Iterator invalidation rules , scoreVector.push_back(x);
根据迭代器失效规则, scoreVector.push_back(x);
may invalidate iterators taken before that by causing reallocation.可能会导致重新分配,从而使之前采用的迭代器无效。
You should save indice instead of iterators as indice.您应该将索引而不是迭代器保存为索引。
Also be careful because erase
will shift following elements and it may affect indice of the element to be erased.还要小心,因为erase
会移动后面的元素,它可能会影响要擦除的元素的索引。
Try this:尝试这个:
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <limits.h>
using namespace std;
typedef vector<int>::iterator iter;
int main() {
cout << "Please enter the series of scores: \n";
// Read numbers from the standard input
// and store them in a vector
vector<int> scoreVector;
int x = 0;
int count = 0;
// Assign the lowest possible value to the maximum possible integer so that any value entered initially will be lower that INT_MAX
int lowestValue = INT_MAX;
int highestValue = 0;
size_t lowestValueIndex = 0;
size_t highestValueIndex = 0;
// Every time a number is entered, the program checks to see if it meets the criteria for the lowest or highest number entered so far
while (cin >> x) {
scoreVector.push_back(x);
if (x > highestValue) {
highestValueIndex = scoreVector.size() - 1;
highestValue = x;
}
if (x < lowestValue) {
lowestValueIndex = scoreVector.size() - 1;
lowestValue = x;
}
}
// Calculate the vector size
auto n = scoreVector.size();
if (n > 2) {
cout << "\nThe lowest value is:" << lowestValue << "\nThe highest value is: " << highestValue << ". These values have been taken out." << '\n';
// Remove the two values from the vector
scoreVector.erase(std::next(scoreVector.begin(), lowestValueIndex));
if (lowestValueIndex < highestValueIndex) highestValueIndex--;
scoreVector.erase(std::next(scoreVector.begin(), highestValueIndex));
// Calculate the average
auto average = accumulate(scoreVector.begin(), scoreVector.end(), 0.0) / n;
cout << "\naverage = " << average << '\n';
}
return 0;
}
Inside your while
loop, you are taking iterators to scoreVector
.在while
循环中,您将迭代器带到scoreVector
。 However, every time you do a push_back
on a vector
, all iterators to it are invalidated.但是,每次对vector
执行push_back
时,它的所有迭代器都会失效。 This means that when you exit your while
loop, at least one if not both iterators are dangling.这意味着当您退出while
循环时,如果不是两个迭代器,则至少有一个是悬空的。 Passing those iterators to .erase
then invokes undefined behavior.将这些迭代器传递给.erase
然后调用未定义的行为。
Instead, you should separate out the reading of the variables, and computation of the iterators that you want to erase:相反,您应该将变量的读取和要擦除的迭代器的计算分开:
while (cin >> x) {
scoreVector.push_back(x);
}
iter lowestValueIndex = std::min_element(scoreVector.begin(), scoreVector.end());
scoreVector.erase(lowestValueIndex);
iter highestValueIndex = std::max_element(scoreVector.begin(), scoreVector.end());
scoreVector.erase(highestValueIndex);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.