从向量和成对向量中擦除元素的区别

时间:2018-07-04 11:44:56

标签: c++ vector std-pair

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    vector<int>p;
    p.push_back(30);
    p.push_back(60);
    p.push_back(20);

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i]<<" ";
}

上面的代码引发错误,因为可以理解p.end()指向空指针。

以下代码运行正常,输出为3060。有人可以解释吗?

#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
int main() 
{
    vector<pair<int,int>>p;
    p.push_back(mp(30,2));
    p.push_back(mp(60,5));
    p.push_back(mp(20,7));

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i].first<<" ";
}

2 个答案:

答案 0 :(得分:3)

来自std::vector::erase

  

迭代器pos必须有效且可取消引用。因此,end()迭代器(有效,但不可取消引用)不能用作pos的值。

因此,您的代码在两种情况下均无效,并调用undefined behaviour。这意味着任何事情都可能发生,包括崩溃,工作或任何需要的事情。

答案 1 :(得分:1)

  

上面的代码会引发错误,因为可以理解...

不保证该代码“引发错误”。而是,行为是不确定的。引发错误是一种可能的行为。如果确实发生错误,您可以算是幸运的,否则可能很难找到您的错误。

  

...据了解,p.end()指向空指针。

否,p.end()不“指向空指针”。它指向向量的末端,其中向量的末端被定义为最后一个元素之后的位置。

  

以下代码运行正常,输出为3060。有人可以解释吗?

未定义行为时,可能的行为是“运行正常”和“输出为30 60”。未定义时,一切都是可能的行为。但是,当然不能保证它会正常运行。就语言而言,该程序明天也可能无法正常运行。

  

我已经在许多在线编译器上进行了检查,但是输出是相同的!

在未定义行为的情况下,许多在线编译器上的输出相同也是可能的行为。无法保证某些编译器的行为会有所不同,就像无法保证它们具有相同的行为一样。

无论尝试使用多少个编译器,都无法仅通过执行程序并观察所需的输出来验证程序是否正确。证明程序正确的唯一方法是,验证所有的前提条件和施加在程序上的不变性。