2014-09-03 59 views
0

我有一個不尋常的情況。 這裏的片段:不正確的2D陣列訪問

int i, j; 
short ** s = (short **)malloc(128); 
for(i = 0; i < 14; i++){ 
    s[i] = (short *)malloc(128); 
    for(j = 0; j < 128; j++) 
     s[i][j] = 0; 
} 
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]); 
s[1][108] = 99; 
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]); 

輸出我得到當我運行是這樣的:Value of s[2][40] = 0 Value of s[2][40] = 99

消除環路,寫短S [14] [128]產生正確的輸出(S的值[2 ] [40]在這兩個打印中都爲0)

爲什麼我能用s [1] [108]訪問s [2] [40]? 我在Ubuntu 12.04上使用gcc。

+0

OT:即使你有一個語句一個循環,你應該始終把括號(好習慣) – 2014-09-03 11:26:30

+1

[請不要投的返回值'C中的malloc()'](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – unwind 2014-09-03 11:29:44

回答

6

您正在訪問您分配空間的界限,這會導致未定義的行爲。

s[i] = (short *)malloc(128)分配128字節。但是,你試圖在這個空間寫128條短褲。由於空格大於1個字節,因此您將分配結束。

另外,short ** s = (short **)malloc(128);可能會分配太多空間,因爲您只使用14行。

假設要的14×128的方式的陣列是:

short **s = malloc(14 * sizeof *s); 
for (size_t i = 0; i < 14; ++i) 
    s[i] = malloc(128 * sizeof *s[i]); 

malloc需要的字節數,所以你必須通過每個元件的尺寸乘以元素數。

請注意,如果你並不需要的是能夠使不同行不同的尺寸,那麼該功能,你可以在一個單一的集團將它分配:

short (*s)[128] = malloc(14 * sizeof *s); 

,並在這兩種情況下,你可以使用s[i][j]相同。

最後,您還應該檢查malloc返回的指針不是NULL,也不是free指針在完成存儲器之後。

+0

是的。我忘記了malloc佔用了我的系統中的字節數和一個short是2個字節。非常感謝。 – PrithviJC 2014-09-03 16:46:24

0

首先,它不是爲2D分配內存的正確途徑基於陣列

short ** s = (short **)malloc(128); 
for(i = 0; i < 14; i++){ 
    s[i] = (short *)malloc(128); 

這是走錯了路!

short ** s = (short **)malloc(128); 

這裏您將爲short **分配128字節的數組的內存。

for(i = 0; i < 14; i++){ 
    s[i] = (short *)malloc(128); 

但是您僅使用14 short *。這隻使用了28個字節(因爲sizeof(short)= 2)。

爲什麼我能夠訪問s[2][40]s[1][108]? - 因爲您正在訪問數組越界!

怎麼樣?

s[i] = (short *)malloc(128); 

這將爲每個short *分配128字節的數組的內存。這意味着您可以在每個1D數組中存儲最多64個短元素。

但您試圖訪問s[1][108] - 表示數組第一行中的第108個元素。它超出了分配的內存。所以你不會得到預期的輸出。

嘗試分配內存喜歡這個 -

short **s = malloc(sizeof(short *) * 14); 
for(i = 0; i < 14; i++){ 
    s[i] = malloc(sizeof(short) * 128);