当应用于向量时,我在理解C ++ clear函数的行为方面遇到了一些困难。
我尝试编译并运行以下函数:
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
unsigned int i;
vector<int> myvector;
myvector.push_back (1);
myvector.push_back (2);
myvector.push_back (3);
cout << "myvector contains:";
for (i=0; i<myvector.size(); i++) cout << " " << myvector[i];
myvector.clear();
myvector.push_back (11);
myvector.push_back (12);
cout << "\nmyvector contains:";
for (i=0; i<myvector.size(); i++) cout << " " << myvector[i];
cout << endl;
cout << " entry3 = " << myvector[2]<<endl;
return 0;
}
这是输出:
myvector contains: 1 2 3
myvector contains: 11 12
entry3 = 3
清除向量时,如何才能删除向量的第三个条目的信息?
答案 0 :(得分:23)
来自文档:
向量的所有元素都被删除:调用它们的析构函数,然后从向量容器中删除它们,使容器的大小为0.
基本上,您在myvector[2]
上调用未定义的行为,因为该项目已不存在。调用clear()
后,您只在向量中推送了2个元素,因此只能访问索引0
和1
。
你不幸的是它没有崩溃,因为看似工作可以隐藏错误。无法保证该值被删除。
尝试使用.at(2)
访问元素会导致抛出异常(operator[]()
不执行任何边界检查,而at()
则执行此操作。)
答案 1 :(得分:7)
如果您尝试在debug
模式下运行此代码,则可能会因调试断言而崩溃。超出数组末尾的引用是未定义的行为。
实际发生的事情是,在您运行clear()
之前,矢量尚未擦除之前使用的内存。此内存仍然存在,但未定义如果访问它将会发生什么。由你来执行边界检查以避免在向量的末尾运行。您可以通过使用size()
作为边界循环,或使用at()
并捕获out_of_range
异常来执行此操作。我不会特别推荐后一种方法,因为使用异常进行运行时检查不是一个好主意。