繁体   English   中英

表达式:使用 vector.erase() 时向量擦除迭代器超出范围

[英]Expression: vector erase iterator outside range when using vector.erase()

我是 C++ 新手,并试图编写一个程序,该程序采用向量中的最低和最高数字,将它们从向量中取出并继续计算其余数字的平均值。

现在,虽然我知道我可以在输入数字后做到这一点,但我想挑战自己并在数字一个一个输入时进行这些检查。 我环顾四周,但找不到与我遇到的确切问题有关的另一个人(因为我使用的是 vector.end() - 1)。

下面是我的代码和它给我的错误。 非常感谢任何指导。

    #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;
    }

在此处输入图片说明

根据迭代器失效规则scoreVector.push_back(x); 可能会导致重新分配,从而使之前采用的迭代器无效。

您应该将索引而不是迭代器保存为索引。

还要小心,因为erase会移动后面的元素,它可能会影响要擦除的元素的索引。

尝试这个:

    #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;
    }

while循环中,您将迭代器带到scoreVector 但是,每次对vector执行push_back时,它的所有迭代器都会失效。 这意味着当您退出while循环时,如果不是两个迭代器,则至少有一个是悬空的。 将这些迭代器传递给.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM