簡體   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