为什么程序在C ++中遍历空向量时会抛出运行时错误

时间:2020-02-13 13:45:51

标签: c++ vector

vector <int> o;    //Empty vector
for(int i=0;i<=o.size()-1;i++) cout<<o[i]; 

在上面得到运行时错误

vector <int> o;  
for(auto j : o){
 cout<<j<<" ";
            } 

但是,如果改用 iterator ,则此代码可以正常运行

3 个答案:

答案 0 :(得分:14)

C ++标准要求

o.size()返回unsigned类型。当它为零时,减去1得出std::numeric_limits<decltype(o.size())>::max(),这意味着您的循环超出了空向量的边界。

for(std::size_t i = 0; i < o.size(); ++i)是显而易见的解决方法。对我来说,<=-1的使用似乎毫无意义。

答案 1 :(得分:6)

o.size()将返回无符号值0。从中减去一个将返回非常大的正数,从本质上讲是一个无限循环。最终,您对o[i]的越界访问将导致崩溃。

您可以使用

for(int i = 0; i <= int(o.size() - 1); i++)

或者只是使用更典型的

for(int i = 0;i < o.size(); i++)

检查“小于”,而不是“小于或等于”一个数字。

答案 2 :(得分:2)

由于sizeof(size_t)大于或等于sizeof(int)(尽管这可能取决于实现),并且size_tunsigned,所以int({{1 }})转换为1

因此,在表达式size_t中,o.size() - 1被隐式转换为1,并且size_t(等于o.size() - 1)等于size_t(0 - 1)。因此,将进入std::numeric_limits<size_t>::max()循环,并在索引for处访问空的o会导致行为未定义。

您应该:

0

如果由于某种原因您需要索引的类型为for (size_t idx = 0; idx < o.size(); ++idx) { /* ... */ } ,则可以:

int

或在您的示例中(这种情况较不常见):

for (int idx = 0; idx < static_cast<int>(o.size()); ++idx) { /* ... */ }