2017-10-06 47 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++編程時,你根本不會犯任何錯誤。沒有「運行時錯誤天使」來保護你,就像其他更高級的語言一樣。