2011-12-01 39 views
1

我需要一個字符串數組,其中在編譯時不知道數組的長度。我所做的是:動態調整字符串數組的大小

char **words; 

words = malloc(capacity * sizeof(char *)); 

char nextword[MAX_LEN + 1]; 

while (true) { 
    if (num_entries == capacity) { 
     capacity += 5; 
     realloc(words, (sizeof(char *) * capacity)); 
    } 

    printf("\nEnter a word: "); 
    fgets (nextword, MAX_LEN, stdin); 

    remove_newline(nextword); 

    if (strlen(nextword) == 0) break; 

    words[num_entries] = malloc(strlen(nextword + 1)); 

    if (words[num_entries] == NULL) { 
     printf("\nout of space\n"); 
     break; 
    } 

    strcpy(words[num_entries], nextword); 
    num_entries++; 

這似乎工作,一旦擴大規模,但擴容後的第一個元素已經成爲NULL出於某種原因。第二次realloc執行我得到一個錯誤:

"invalid next size" .

回答

5

你的代碼幾乎就在那裏,只需要一些修改。一個重要的事情要記住的是,realloc不會修改您傳遞給它的值,並且不需要將指針返回到您傳遞給它的同一塊內存。 Here is a working example of using realloc。這很簡單,所以你應該可以通過簡單的例子來修復你的代碼。

char **more_words = realloc(words, capacity); 
if (more_words) { 
    words = more_words; 
} else { 
    // Do something about realloc failure 
} 
+0

感謝您的鏈接。它非常有幫助。 – Wcrousse

+0

鏈接很好,但是在計算器中,如果鏈接不再工作,則需要直接在此處顯示解決方案。 –

+0

@YohanObadia代碼不是必需的,只要解釋足以找出問題所在。解決方法是通過解釋問題所在(我的意思是「realloc不會修改您傳遞給它的值」部分)。 – dasblinkenlight

7

realloc不能保證給你回相同的內存塊,因爲最初從堆中分配的塊可能沒有足夠的空間來容納你新的請求大小。在這種情況下,您將返回一個新的內存塊,並將您的舊數據複製到該內存塊。

您需要捕獲每個循環的返回值,並使用它來檢查您所期望的數據,並檢查它是否爲0(如果realloc無法完成)。

words = realloc(words,..) 

是一個反模式 - 避免這種情況,因爲舊的記憶可能會丟失,如果realloc失敗。