2015-02-24 43 views
0

試圖分配一個由N個元素組成的char數組。動態字符數組

#include <stdio.h> 
#include <malloc.h> 

int main() 
{ 
    int N = 2; 

    char *array = malloc(N * sizeof(char)); 

    array[0] = 'a'; 
    array[1] = 'b'; 
    array[2] = 'c'; // why can i do that?? 

    printf("%c", array[0]); 
    printf("%c", array[1]); 
    printf("%c", array[2]); //shouldn't I get a seg fault here?? 

    return 0; 
} 

的問題是:

由於我分配2 * 1 = 2個字節的存儲器,這意味着,我可以在我的陣列2個字符。我怎麼可能有更多?我還打印sizeof(*數組),它打印8個字節。我在這裏錯過了什麼?

+4

這是*未定義的行爲*。高興你的貓沒有着火。 – Zeta 2015-02-24 18:33:19

+3

如果你經過數組的末尾(這是未定義的行爲),C並不在乎。只要這個內存存在,它就會有*機會*,這取決於你的編譯器,操作系統和其他東西。然而,你的編譯器應該給你一個警告。 – Jon 2015-02-24 18:34:27

+2

'sizeof(* array)'應該是1,而不是8.也許你打印了'sizeof(array)',它給出了一個指針的大小。 – interjay 2015-02-24 18:34:40

回答

2

當程序嘗試訪問未被操作系統映射到其虛擬內存地址空間的內存地址時,會發生分段錯誤。

內存分配發生在頁面中(通常是4k或8k,但你也可以得到更大的頁面)。所以malloc()調用從操作系統獲取一個內存頁面,併爲它分割出一部分,並返回一個指向它的指針。在這種特定情況下,數組之後仍有大部分頁面(未分配,但已用於後續對malloc())的調用 - array [2]引用頁面內的有效地址,因此不存在分段錯誤。

但是,您正在訪問超出數組範圍的內存,如註釋中所述,這是未定義的行爲,可能會通過覆蓋無關變量的值而導致較大程序中的內存損壞。

+0

實際上......在大多數平臺上(無論如何32位或64位),精確的示例顯示不會導致任何重要的損壞。幾乎所有的'malloc'實現都爲指針分配至少*足夠的空間。這就是說,它仍然是不確定的行爲,是一種可怕的做法。 – 2015-02-24 18:53:12

+0

哈哈 - 好點:) – isedev 2015-02-24 18:53:55

+0

所以這個工程,因爲我正在訪問的內存存在,但它不是數組的「部分」。 – pirox22 2015-02-24 18:56:13

0

第0個和第1個元素位於有效內存分配內部。用第二個元素,你已經侵入未分配的內存。將工作正常,直到內存的一部分被分配給其他東西,然後你的第2個元素將開始有瘋狂的價值觀。你的代碼會變得瘋狂。但正如@jon指出的,編譯器應該能夠捕捉到這一點,除非你已經要求它關閉它。

+0

我使用的是gcc,它不打印任何警告:/ – pirox22 2015-02-24 19:32:16

+0

我錯誤地確信gcc本身應該能夠捕捉到這一點,但沒有它沒有。試過夾板。除了這個邊界檢查外,它還捕獲了其他問題。奇怪。 – 2015-02-24 20:09:27