2012-10-11 83 views
15

我在理解C++ clear函数的行为时,遇到了一些困难,当应用于向量时。vector :: clear in C++

我试图编译并运行以下功能:

#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 

这怎么可能是向量的第三项的信息,也没有清除矢量时已被删除?

+2

operator []不是长度验证索引。用.at(n)尝试相同的操作,看看会发生什么。 – WhozCraig

回答

22

从文档:

所有向量的元素将被丢弃:他们的析构函数被调用,然后将它们从载体容器移除,留下容器的大小为0。

基本上你正在调用未定义的行为myvector[2]因为该项目不再存在。在调用clear()之后,您仅向矢量推送了2个元素,因此只有索引01可以访问。

你很倒霉,它没有崩溃,因为看起来工作可以隐藏错误。不能保证价值被抹去。

尝试使用.at(2)访问元素将导致引发异常(operator[]()不执行任何绑定检查,而at()会)。

7

如果您尝试在debug模式下运行此代码,它很可能会因调试断言而崩溃。引用过去数组的末尾是未定义的行为

实际发生的情况是,在您运行clear()之前,矢量并未消除之前使用的内存。这个内存仍然存在,但没有定义如果你访问它会发生什么。这取决于你执行边界检查以避免运行矢量的末端。您可以通过以size()作为边界循环或使用at()并捕获out_of_range例外来完成此操作。我不会特别推荐这种后一种方法,因为使用异常进行运行时检查并不是一个好主意。