2012-03-02 48 views
0

考虑此程序:C++矢量奇怪的行为

#include <iostream> 
#include <vector> 

using namespace std; 

int main(void) 
{ 
    vector<double> a; 
    while (a.size() <= 10) 
     a.push_back(2); 
    cout << a[15] << endl; 
} 

我希望当被问及访问的15个元素让它崩溃,但它没有(我的系统上输出0)。是什么赋予了?这是gcc中的一些新功能吗?

+2

它可能会崩溃,它可能不会。这是未定义行为的美妙之处。 – Mysticial 2012-03-02 15:25:11

+0

停止说..矢量可以增长他们的能力!如果你进行测试,你会看到他的矢量有16个容量,这意味着[15]是有效的! – 2012-03-02 15:45:19

+2

@riskio'a [15]'只有在'a.size()> 15'时才有效。否则,根据标准它是未定义的行为。 (事实上​​,它可能会崩溃,在调试版本。) – 2012-03-02 16:13:54

回答

0

operator[]没有边界检查,在这种情况下,您是* un *幸运的,并且可以读取该位置的地址而不会导致运行时错误。

3

您正在访问导致未定义行为的无效内存位置。所以什么都可能发生。

0

这并不奇怪..当它插入a.size() - 1元素时,它的尺寸会增大它现在你有20种元素..(可能不是20但是超过11(=)

+0

在这个微不足道的例子中,在现实世界中什么位置可以工作,谁知道那个位置是什么。存储可能在那里,但是没有在该站点构建的对象 - 因此访问它是未定义行为 - endof。 – Nim 2012-03-02 15:58:39

+0

它不是一个advice..i没有回答他的question..but C++程序员应该知道STL容器,应该知道,内存管理它的所有的责任,因此在每一个C++程序员S上的责任,做更安全的东西.. – 2012-03-02 16:04:12

-1

我正在阅读的记忆是你的程序也不会崩溃,C++不边界检查

+0

它在标准中说什么?至少如果将正确的选项传递给编译器,我使用的'std :: vector'的实现将进行边界检查。 (他的代码与克崩溃++,当与'-D_GLIBCXX_DEBUG' ---应通常用于所有编译的选项编译,直至探查另有说。) – 2012-03-02 16:21:53

0

因为当你访问它的向量的增长可能会大于15?

检查内capacity()

+0

'capacity()'在这里是不相关的(只能保证大于11)。它的大小()是重要的。 – 2012-03-02 16:15:04

+0

不,'capacity()'返回分配的存储容量的大小。 'size()'返回容器中元素的个数。 – 2012-03-05 09:02:43

+0

这是如何使它在这里相关? (或者与我所说的矛盾。)所有'capacity()'的保证是,在大小超过它返回的值之前,不会有重新分配(并且没有迭代器失效等)。它不会**授权访问超出初始化值的末尾,实际上,好的实现不会允许它,至少在调试模式下。 – 2012-03-05 09:36:53

1

This references说它

返回向量 容器在位置Ñ一个参考元件。

类似的成员函数,矢量::在,具有相同的行为,因为这 操作员功能,不同之处在于矢量::在信号如果所请求的 位置超出范围通过抛出异常。

所以,这可能会或可能不会崩溃。

+0

是的,请使用()如果你想边界检查。 – 111111 2012-03-02 15:32:26

+0

是的,我看了一下,从那个参考文献中不清楚如果n超出范围会发生什么。如果他们明确表示n越界会导致未定义的行为,我就不会问这个问题。 – user818794 2012-03-02 15:36:57