【问题标题】:Segmentation fault on erasing the last element from the vector C++从向量 C++ 中擦除最后一个元素时出现分段错误
【发布时间】:2018-08-01 22:46:08
【问题描述】:

我创建了一个简单的 C++ 程序来测试erase() 在 C++ 向量中的行为。

这是我的代码:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // your code goes here

    vector<int> vec;

    vec.push_back(3);
    vec.push_back(4);
    vec.push_back(5);

    cout << vec[0] << " " << vec[1] << " " << vec[2] << endl;

    vec.erase(vec.end());
    //vec.erase(vec.begin());

    cout << vec.size() << endl;

    vec.push_back(12);
    vec.push_back(10);

    cout << vec[0] << " " << vec[1] << " " << vec[2] << endl;


    return 0;
}

问题是上面的代码在尝试从向量中擦除最后一个元素时给出了分段错误。但是当我使用 begin() 删除第一个元素时,它工作正常。我无法理解其背后的原因。任何帮助将不胜感激。

【问题讨论】:

标签: c++ stl stdvector


【解决方案1】:

问题是std::vector::end 将迭代器返回到容器的最后一个元素之后的元素,而不是最后一个元素

你想要的应该是

vec.erase(vec.end() - 1); // trying to erase the last element of vec

【讨论】:

  • 它会删除最后一个元素吗?我猜它会删除向量的倒数第二个元素。
  • @BhawandeepSingla vec.erase(vec.end() - 1); 将删除最后一个元素。正如我的回答所解释的,std::vector::end 返回的迭代器指向最后一个元素之后的位置。
  • 谁投了反对票...?这是一个完全正确的答案。
  • 问题和随后的答案并不是真的有用。他们没有为网站增加任何价值。答案甚至可能会引发更多糟糕的问题。这个特定的答案在之前的问题中至少出现了九次。
  • 赞成以抵消不公平的反对
【解决方案2】:

vec.end() 为您提供了元素的迭代器跟随容器的最后一个元素。 See here:

试图擦除它是未定义的行为。您应该改为通过以下任一方式擦除:

vec.erase(vec.end() - 1);

或者更好的是使用pop back:

vec.pop_back();

 

【讨论】:

  • 应该提到如果vector为空操作会崩溃,所以为了安全起见if (!vec.empty()) vec.erase(vec.end() - 1);
【解决方案3】:

std::vector::end() 返回一个超过对象最后一个元素的迭代器。它对擦除无效。要从vector 中删除最后一个元素,您需要使用指向最后一个元素的迭代器。

您可以为此使用begin() + size - 1

size_t size = vec.size();
vec.erase(vec.begin() + size - 1);

更好的是,使用std::vector::pop_back()

vec.pop_back();

【讨论】:

    【解决方案4】:

    您需要删除 (vec.end - 1)th 元素,因为 vec.end 指的是向量容器中的过去元素。

    【讨论】:

      【解决方案5】:

      要删除向量的最后一个元素,还可以使用vector::pop_back() 函数。

      例如:

      #include <iostream> 
      #include <vector> 
      using namespace std; 
      
      int main() 
      { 
          vector<int> myvector{ 1, 2, 3, 4, 5 }; 
          myvector.pop_back(); 
      
          // Vector becomes 1, 2, 3, 4 
      
          for (auto it = myvector.begin(); it != myvector.end(); ++it) 
              cout << ' ' << *it; 
      } 
      

      pop_back() 被积极用于涉及回溯的问题,例如查找给定集合的所有可能子集。希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2017-05-22
        • 1970-01-01
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-06
        • 2017-04-17
        相关资源
        最近更新 更多