如題。
今天才發現,原來C++從來不檢查數組索引是否越界。訪問數組元素,比如a[3]
時,編譯器其實已經處理成了*(a+3)
,這時候已經沒有數組的概念了,檢查數組長度就更無從談起。
這一特性使我遇到了一個非常大的BUG,把它簡化成下面的代碼:
#include <iostream>
int main() {
double d[3] = {0, 1, 2};
double dd = 9;
d[3] = 0;
std::cout << dd << std::endl;
return 0;
}
輸出結果是0而不是9。
也就是說,給d[3]
賦值實際上賦到了dd
頭上去了。因為數組d
和變量dd
被依次定義,它們被安排在同一塊內存空間的相鄰位置,于是d[3]
實際指向的是dd
的內存空間,因此dd
被改寫。
在實際編程中,這樣的問題很容易出現,但非常難排查。被覆蓋的變量可以是基本數據類型,也可以是變量,還可以是指針。而且有時候變量并不一定按照定義時的順序排列在內存中,編譯器完全有可能做了額外的優化,重排這些變量的位置。據說C++是為了提高效率,才弱化了安全保護機制,畢竟兩者不可兼得。
編程難,編C++更難,且編且珍惜。