C 陣列超界錯誤

2021-10-25 10:28:03 字數 2890 閱讀 9071

在正常情況下,為陣列元素賦值時,陣列array的索引應當在 [0, (sizeof(array)/sizeof(array[0]))-1]。但當陣列索引為負數時,例如

double array[4]

;array[-2

]=1.5;

此時會發生什麼呢?

示例取自c++ primer plus 第六版(stephen prata)第四章復合型別 4.10陣列的替代品 程式清單4.2 choice.cpp

#include

#include

#include

using

namespace std;

intmain()

; vector<

double

>a2(

4); a2[0]

=1.0

/3.0

; a2[1]

=1.0

/5.0

; a2[2]

=1.0

/7.0

; a2[3]

=1.0

/9.0

; array<

double,4

> a3 =

; array<

double,4

> a4;

a4 = a3;

cout <<

"a1[2]: "

<< a1[2]

<<

" at "

<<

&a1[2]

<< endl;

cout <<

"a2[2]: "

<< a2[2]

<<

" at "

<<

&a2[2]

<< endl;

cout <<

"a3[2]: "

<< a3[2]

<<

" at "

<<

&a3[2]

<< endl;

cout <<

"a4[2]: "

<< a4[2]

<<

" at "

<<

&a4[2]

<< endl;

a1[-2

]=20.2

; cout <<

"a1[-2]: "

<< a1[-2

]<<

" at "

<<

&a1[-2

]<< endl;

cout <<

"a3[2]: "

<< a3[2]

<<

" at "

<<

&a3[2]

<< endl;

cout <<

"a4[2]: "

<< a4[2]

<<

" at "

<<

&a4[2]

<< endl;

system

("pause");

return0;

}

程式結果為:

a1[2]

:3.6 at 0x28cce8

a2[2]:

0.142857 at 0xca0328

a3[2]:

1.62 at 0x28ccc8

a4[2]:

1.62 at 0x28cca8

a1[-2]

:20.2 at 0x28ccc8

a3[2]:

20.2 at 0x28ccc8

a4[2]:

1.62 at 0x28cca8

不同情況下,程式執行結果並不同。書中給出的結果中,a3[2]的值也被更改為 20.2。而我的執行結果中a3[2]依然為 1.62。為什麼會出現此種情況?

程式重點介紹陣列、vector物件、array物件的相似和不同之處,但也介紹了一種陣列超界錯誤,即

a1[-2

]=20.2

;

該語句將被轉化為:

*

(a1-2)

=20.2

;

其含義為:找到a1指向的地方,向前移動兩個double元素,並將20.2儲存到目的地,即將資訊儲存到陣列的外面。

可以發現,a1[2]儲存位址為0x28cce8,double型別佔8 bytes,可得a1[-2]的儲存位址為0x28ccc8,正好為a3[2]的儲存位址,因此a3[2]的值被覆蓋為20.2。也可以說這是因為,a1[-2]a3[2]指向同一塊記憶體。

而如果a1[-2]並未與程式中其他元素的位址重合,則不會出現其他元素一起被修改的意外情況。

書中給出了一種避免該情況出現的選擇,使用成員函式at()

a2.at(

1)=2.3

;// assign 2.3 to a2[1]

中括號表示法和成員函式at()的差別在於,使用at()時,將在執行期間捕獲非法索引,而程式預設將中斷。這種額外檢查的代價是執行時間更長,這就是 c++ 允許使用任何一種表示法的原因所在。使用 vector 和 array 等類能夠降低意外超界錯誤的概率,將在後面進一步討論。

十九 位移超界

段內短轉移 移動範圍 128 127 jmp short 標號 段內近轉移 移動範圍 32768 32767 jmp near ptr 標號 段內短轉移 移動範圍 128 127 jcxz 標號 段內短轉移 移動範圍 128 127 loop 標號 位移指令使用時,位移範圍是受到限制的。在使用位移指...

C語言二維陣列超細講解

用一維陣列處理二維 實際是可行的,但是會很複雜,特別是遇到二維 的輸入 處理和輸出。在你絞盡腦汁的時候,二維陣列 一維陣列的大哥 像電視劇集裡救美的英雄一樣顯現在你的面前,初識陣列的朋友們還等什麼呢?讓我們認識一下這位武功高強的大哥吧!聰明的你一定能夠顧名思義了吧,簡單舉個例子 array 2 3 ...

Delphi2009 泛型容器遍歷超界問題

今天用tdictionary,發現居然乙個成員的集合遍歷裡有2次。就是下面簡單的遍歷 varlpair tpair begin for lpair in fformdictionary do begin tform lpair.value free end 導致fff0006c的記憶體溢位!網上搜尋...