2017-10-06 49 views
0

我有一个最小的代码之后的行为:根本原因为不同的输出在去除打印语句“出的矢量误差的范围”

vector<int> result(9); 
int count = 0; 
cout << "test1\n"; // removing this line causes 'core dump' 
for (int j=0; j < 12; j++)   
    result[count++] = 1; 
cout << "test2\n"; 

结果是尺寸9的载体,和'for'循环我正在访问超出范围的元素。

现在,除去TEST1线,代码运行没有任何错误;但与此COUT线,我得到

*错误的`./out_of_range_vector2' :免费():无效的下一个尺寸(快速):0x0000000001b27c20 *

我明白,这告诉我,免费()遇到了未分配我的malloc()一些内存,但什么样的作用这是否COUT线在这里踢球?我想更多地了解这里发生的事情。更具体地讲,我有两个问题:

  1. 是这个引起的对这些2箱子不同的状态?如果是这样,究竟有什么不同?
  2. 为什么有时范围内的元素进行访问不会导致错误?是因为它没有超过矢量的容量?
+4

走出界限会导致[* undefined behavior *](http://en.cppreference.com/w/cpp/language/ub),这就是故事的结尾。 –

+0

根据定义,未定义的行为是未定义的。 –

+1

如果你对范围检查感兴趣,可以考虑['std :: vector :: at'](http://en.cppreference.com/w/cpp/container/vector/at)。 –

回答

0

线

cout << "test1\n"; 

做了很多事情,它都不可能分配的可用内存。

写一个向量的范围之外是“不确定的行为”,这是由“得到一个错误”非常不同。的“未定义行为”的含义是,谁写的编译器和运行时库根本可以忽略那些可能性,无论发生什么情况。他们可以这样做,因为程序员永远不会做这些事情,确实当它是100%的他/她的错。预防,保护或访问使用operator[]不是合同的一部分std::vector元素时甚至简单地通知错误。

从技术上讲,可能发生的事情是写操作会破坏内存分配器使用的一些内部数据结构,并导致出现可能导致段错误或不导致段错误的疯狂行为。

段错误是当事情变得疯狂时,即使操作系统可以检测到程序没有做它应该做的事情,因为它请求访问甚至不存在的位置(所以肯定它们不可能是正确的位置应该包含正在查找的数据)。

但是,即使没有从正确的程序中获得任何可观察的差异,您也可以获取未定义的行为和损坏的数据,而不会进入该“segfault”点,程序将简单地从错误的位置读取或写入错误的数据。这实际上是大多数时候发生的事情(不幸的是)。

那么当您使用未检查的opertor[]std::vector的尺寸之外读取或写入时发生了什么?大部分时间没有(显然)。然而,在错误之后,它可能会做任何事情,包括在代码正确的地方表现得很疯狂,以后会有十亿次机器指令,并且只有在引起严重损害的情况下。只是不要那样做。

用C++编程时,你根本不会犯任何错误。没有“运行时错误天使”来保护你,就像其他更高级的语言一样。