2013-12-07 167 views
2

我正在學習C並試圖構建一個動態數組。我發現了一個很棒的教程,但我並沒有完全掌握它。我現在的代碼是C動態數組元素訪問

typedef struct{ 
    int size; 
    int capacity; 
    char *data; 
}Brry; 

void brry_init(Brry *brry){ 
    brry->size = 0; 
    brry->capacity = 2; 
    brry->data = (char *)calloc(brry->capacity, sizeof(char)); 
} 

void brry_insert(Brry *brry, char value){ 
     brry->data[brry->size++] = value; //so do check here if I have enough memory, but checking something out 
} 

int main(void){ 
    Brry brry; 
    brry_init(&brry); 

    for (int i = 0; i < 3; i++) { 
     brry_insert(&brry, 'a'); 
    } 

    printf("%c\n", brry.data[2]); 
    return 0; 
} 

在我的主要功能我加3元到數組,但只分配給2.但是,當我打印出來它工作得很好?我期望打印一些奇怪的值。爲什麼這個或我做錯了什麼?

+1

請注意'brry.data [3]'是第四個元素。 – Novak

+0

對不起復制過去的錯誤 – Haagenti

+0

這是[undefined behavior](http://stackoverflow.com/a/367662/1113392) – A4L

回答

3

您正在寫入未分配足夠內存的緩衝區。它的工作原理不能保證。

你現在正在嘗試從內存中的某些垃圾值中讀取數據,誰知道,這有時會導致分段錯誤,其他時候你很幸運並獲得一些垃圾值,並且它不會發生段錯誤。

寫入垃圾內存將調用未定義的行爲,所以最好觀察它。 如果確實發生錯誤,它幾乎總是一個段錯誤,是段錯誤的縮寫。 閱讀它here

通過讀取數組的界限,你所做的技術稱爲去除一個指針。您可能還想了解更多關於here的信息。

+0

錯誤的方式。 如果你幸運的話,你會得到一個seg故障,並且知道你現在已經站起來而不是「有效」了,並且有人在路上會有某種致命的錯誤,可能會導致該公司數百萬美元由於工資損失,維修/重新設計費用等造成的損失。 – ciphermagi

+0

@JonahNelson是的,有時候你會很幸運知道。但是我們希望OP從中學到一些東西。 – edwardmp

1

是的,你的確在寫入一個兩元素數組的第三個元素。這意味着您的程序將顯示未定義的行爲,您無法保證將發生什麼。在你的情況下,你很幸運,該計劃「工作」,但你可能並不總是如此幸運。

1

試圖讀取/寫入數組的末尾會導致未定義的行爲。究竟發生了什麼取決於幾個你無法預測或控制的因素。有時候,它似乎無需抱怨即可成功讀取和/或寫入。其他時候,它可能會導致程序崩潰並且非常有效。

關鍵的是你永遠不應該嘗試使用或依賴未定義的行爲。不幸的是,這是一個常見的菜鳥錯誤,認爲它會一直工作,因爲一次測試成功了。這絕對不是這種情況,遲早會造成災難。