標籤:

C++數組有一個致命缺陷,為什麼一直沒有人發現?

C++的數組真的是一點也不嚴謹。我定義了一個int類型的數組a。int a[5], 這個數組的大小應該是五,只能夠存五個int類型的元素。但是我偶然發現,我可以使用a[5]來存元素,但是a[5]是不存在的,因為我創建的數組只有a[0]到a[4]。我還發現不但a[5]可以用,a[6],a[7],a[8]都可以用。C++的數組存在這麼大的問題,為什麼一直沒有人發現呢?


這就相當於,你買了100平米的院子用來堆東西,然後你發現100平米外也能放東西,還沾沾自喜,但是那是你鄰居老王的院子,人家說不定哪天就把你放的東西扔走放自己的了。


一般人的邏輯:
為什麼可以給a[6],a[7]賦值還能輸出——&>查詢原因——&>了解原理。

題主的邏輯:
可以給a[6],a[7]賦值還能輸出——&>肯定是沒人發現的錯誤——&>知乎發帖炫耀。


你發沒發現 a[-1], a[-2], a[-3] 也是可以用的哎!

0[a], 1[a], 2[a] 也是可以用的哎!

-1[a], -2[a] 也是可以用的哎!


用「幽靈」這個詞是打算致敬貝克萊主教嗎?

正經地說:內建數組(這裡暫時只討論左值)定址時,數組表達式要先隱式轉換成沒有長度信息的指針表達式,自然就不可能有越界檢查了。

想要檢查可以用 std::array::at 和 std::vector::at 。


我的天啊,這是民科準備入侵C++的節奏了嗎


這種行文方式只會讓人想到民科啦。

說個大概有點關係的事實,MSVC STL的std::vector在debug模式下自帶邊界檢查,結果慢了一百倍以上,有些人直接嫌debug模式下的std::vector不能用了。


你沒發現不僅a[5]可以,5[a]也可以嗎?-5[a]沒準也可以呀。
――――――――――――――――――――
曾經一位老師跟我說「如果你在沒有努力鑽研的情況下靈光一閃就有了一個絕妙的想法,多半是讀書少。」,共勉!
――――――――――――――――――――
改個錯別字,鑽研,謝謝提醒


其他回答回答已經很好了 推薦使用 std::array

其實這個缺點顯而易見。但是為什麼會出現這種現象?
學過彙編或者體系結構你會知道c這種語言比較嚴格的對應彙編。堆和棧是什麼東西,為什麼會有越界。

學過編譯原理你會感受到可能是C語言成立時間早,當時運行時和編譯時期沒有很好的方法去解決越界。

看過c++之父的c++的歷史與演化,你就會知道為什麼c++繼承了c的缺點。

總之你學的一切知識都可以對這個問題理解有幫助。 但是初學者請不要自己創造一些辭彙。因為你遇到的問題百分之99都有對應的知識。你這麼做一是加大交流成本,二是顯得業餘,感覺會有民科味道。

總之學計算機舉一反三是好的。但是計算機也需要腳踏實地。勿要浮沙築塔。


你用cppcheck或者klocwork把這段代碼掃一下。
不是error就是critical。


先問...再問...(滑稽


這種現象,稱為「越界訪問」。
已經有人發現這種現象了。現在建議使用array和vector數組,而不使用自帶的數組。並且使用at函數可以處理越界訪問的問題。

引用之前的回答:
C++有兩種「數組」。
第一種是array,聲明方式為:
array&<類型,長度&> a;
用途主要是存長度限定或者需要高速運算的內容,比如存世界上所有大洲的名字,只有6個值的哈希臨時數組,或者某人的生日。

另一種是vector,聲明方式為:
vector&<類型&> v;
用途主要是存放長度不定的數據,或者不需要太高性能的場合。

對於字元串,如果不是因為特殊原因要使用array,則可以使用string,聲明方式為:
string s;
string適合數據大部分小於16位元組的場合,或是數據方差較大的場合。但其實string對於其它場合的處理能力也足夠用。

至於自帶的數組b[n],用處有很大的局限,主要用於:
1、隨手寫個簡單的小程序;
2、對性能有非常高的要求;
3、需要使用變長數組和伸縮數組(需要C99支持);
4、編譯器對array支持差。


編譯器看了你的代碼,返回「是是是」後編譯通過。


經過我幾十年的c++編程經驗,發現了c++一個更大的bug
#include &

int main(int argc, char * argv[])
{
int a = 2147483647;
std::cout &<&< a + 1 &<&< std::endl;
}

結果竟然不是 2147483648

c++連最基本的算數運算都有bug,失望


C 語言不具備「默認安全」特性。

早期的編程語言都這樣,後來的 C++ 和 Golang 漸漸就加上了。


講道理,這是C的數組,不是C++的數組。C++為了兼容C不得不把所有的糟粕都拿了過來,但是實際上C++真正的數組是std::array:

array& fucks;
fucks.at(10) = 10;

這樣就會爆炸


那你很棒棒吆~~~


效率和安全不可兼得。——魯迅


多讀書,多看文檔,別剛寫了兩行代碼就想放衛星。


一般這麼萌的題目我都會看看是不是有人來釣魚的。。。


講道理,正經上過大學計算機課的或者MOOC之類的網上課程的,一般不會問出這麼搞笑的問題。

我感覺以後計算機速成培訓班會出來一大批計算機民科。。。


推薦閱讀:

怎麼學習 C++ 類的設計?
如何評價漫畫《NEW GAME!》中人物櫻寧寧的編程水平?
如何通俗的理解機器學習中的VC維、shatter和break point?
為什麼有些編程語言的數組要從零開始算?
前端開發中有什麼經典的輪子值得自己去實現一遍?

TAG:編程 | C | CC |