2017-01-04 76 views
1

我正在寫一些代碼,我用了功能calloc關於calloc的奇怪事情

我明白,當傳遞給這個函數的第一個和第二個參數都是0時,函數將爲0個元素分配必要的空間,每個元素的大小爲0,但這裏是奇怪的事情。

即使n> 0,該程序也能正常工作。爲什麼會發生這種情況?我認爲它應該顯示一個錯誤,因爲我試圖寫入一個不存在的數組位置。謝謝!

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    int n; 
    scanf("%d", &n); 
    int *test = calloc(0, 0); 
    for(int i = 0; i < n; i++){ 
    test[i] = 100; 
    printf("%d ", test[i]); 
    } 
    return 0; 
} 
+6

未定義的行爲意味着會發生任何事情。 – Kevin

+1

無語法錯誤=在'c'中沒有編譯錯誤。你編譯得很好,但是你寫的超出了你的內存區域(當'n> 0'),這是未定義的行爲。 – yano

+1

你不會在c中得到這樣的錯誤。它會嘗試將其寫入指定的地址。你作爲程序員必須小心確保它不會發生。 –

回答

0

在C中,很多錯誤和「錯誤」的東西不會顯示來自編譯器的錯誤消息。事實上,當您運行程序時,甚至可能看不到錯誤信息 - 但另一個在另一臺計算機上運行程序的人可能會看到該錯誤。

用C的一個重要概念就是未定義行爲。簡而言之,這意味着你的程序的行爲是不可預知的,但你可以在這個問題上閱讀更多關於這個主題的文章:Undefined, unspecified and implementation-defined behavior

你的程序是未定義的原因有兩個:

  1. 當任sizenmemb爲零,calloc()可能返回NULL。你的程序沒有檢查calloc()輸出,所以有一個很好的機會,當你做test[i]您正試圖derreference一個NULL指針 - 你應該經常檢查calloc()malloc()結果。
  2. 當你調用malloc()calloc(),你essentialy一個數組分配動態內存。您可以使用指針訪問數組的元素。但你不能訪問任何東西過去陣列。也就是說,如果您分配n元素,則不應嘗試訪問第n+1第 - 個元素 - 不要閱讀。上述

兩個項目使你的程序調用未定義的行爲。有可能也是一個未定義的關於訪問上面列出的項目#2以外的空對象,但我不確定。

對於未定義的行爲,您應該小心謹慎,因爲當您的程序調用UB時,它實質上是不可預知的。您可以看到編譯錯誤,程序可以給出一個錯誤messagen,它可能運行successfuly沒有任何問題或在您的硬盤它可能消滅每一個文件。