#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<<" ";
}
答案 0 :(得分:3)
迭代器pos必须有效且可取消引用。因此,end()迭代器(有效,但不可取消引用)不能用作pos的值。
因此,您的代码在两种情况下均无效,并调用undefined behaviour。这意味着任何事情都可能发生,包括崩溃,工作或任何需要的事情。
答案 1 :(得分:1)
上面的代码会引发错误,因为可以理解...
不保证该代码“引发错误”。而是,行为是不确定的。引发错误是一种可能的行为。如果确实发生错误,您可以算是幸运的,否则可能很难找到您的错误。
...据了解,p.end()指向空指针。
否,p.end()
不“指向空指针”。它指向向量的末端,其中向量的末端被定义为最后一个元素之后的位置。
以下代码运行正常,输出为3060。有人可以解释吗?
未定义行为时,可能的行为是“运行正常”和“输出为30 60”。未定义时,一切都是可能的行为。但是,当然不能保证它会正常运行。就语言而言,该程序明天也可能无法正常运行。
我已经在许多在线编译器上进行了检查,但是输出是相同的!
在未定义行为的情况下,许多在线编译器上的输出相同也是可能的行为。无法保证某些编译器的行为会有所不同,就像无法保证它们具有相同的行为一样。
无论尝试使用多少个编译器,都无法仅通过执行程序并观察所需的输出来验证程序是否正确。证明程序正确的唯一方法是,验证所有的前提条件和施加在程序上的不变性。