2012-11-25 165 views
1

我必須動態分配字數組。單詞存儲在由空白字符變量數分隔的文件中。我不知道文件中有多少單詞是可變長度的。動態字符串數組

我有這樣的代碼:

void readWord(FILE* stream, char *word, char first_c) { 

    word[0] = first_c; 
    char val; 
    int wlen = 1; 
    // isWhitespac is my function - tests if char is blank or '\n' 
    while ((val = fgetc(stream)) != EOF && isWhitespace(val) == 0) { 
     wlen++; 
     word = realloc(word, (wlen+1) * sizeof (char)); 

     word[wlen-1] = val;  

    } 
    word[wlen] = '\0'; 
} 

int readList(const char *file) { 

    FILE* f; 
    char **arr; 
    char val; 
    int wcount = 0; 

    arr = malloc(sizeof (char*)); 
    f = fopen(file, "r"); 

    while (fscanf(f, " %c", &val) == 1) { 
     wcount++; 
     arr = realloc(arr, wcount * sizeof (char *)); 

     arr[wcount - 1] = malloc(sizeof (char)); 

     readWord(f, arr[wcount-1], val); 
     printf("%s\n", arr[wcount-1]); 

    } 


    for (int i = 0; i < wcount; ++i) { 
     free(arr[i]); 
    } 

    free(arr); 

    fclose(f); 
    return 0; 
} 

這似乎做工精細,它讀取打印所有的話。但是當我使用Valgrind運行該程序時,出現了太多錯誤,這是我無法找到的。任何人都可以幫我嗎? (我知道我必須測試malloc和其他人是否正常,這只是一個測試函數。)

Valgrind日誌很長,我應該發佈它嗎?

+1

如果一切正常,它可以唯一的辦法就是由字長你在一個單一頁面分配閱讀方便接頭,這樣' realloc'永遠不需要移動數據。你正在通過* value *而不是地址傳遞你原來的'malloc'指針,所以如果''readWord''中的'realloc'不得不分配一個新頁面並移動數據,你將會有一個懸掛指針回到' readList'並且一旦'readWord'退出就會從新的'word'指針泄漏內存。從這個意義上說,這段代碼絕對不會**「正常工作」。剩下的我留給你和valgrind。 – WhozCraig

+0

你應該把你的代碼放在一些小的東西上來隔離問題。但是那就是說,你並沒有以安全的方式使用'realloc'。請參閱關於此主題的C常見問題解答:http://www.c-faq.com/malloc/realloc.html –

回答

0

其中一個問題是,您在readWord中重新分配內存。如果realloc分配一個新的緩衝區,並且不只是擴展當前的緩衝區,那麼你的代碼就會崩潰(你將雙倍釋放指針),這就是Valgrind所選擇的。爲了解決這個問題,我會重寫代碼,以便它返回一個指針而不是void。

char * readWord(FILE* stream, char *word, char first_c) { 
    word[0] = first_c; 
    char val; 
    int wlen = 1; 
    // isWhitespac is my function - tests if char is blank or '\n' 
    while ((val = fgetc(stream)) != EOF && isWhitespace(val) == 0) { 
     wlen++; 
     word = realloc(word, (wlen+1) * sizeof (char)); 
     word[wlen-1] = val; 
    } 
    word[wlen] = '\0'; 
    return word; 
} 

然後更改readList這個循環:

while (fscanf(f, " %c", &val) == 1) { 
    wcount++; 
    arr = realloc(arr, wcount * sizeof (char *)); 
    arr[wcount-1]=malloc(sizeof(char)); 
    arr[wcount - 1] = readWord(f, arr[wcount-1], val); 
    printf("%s\n", arr[wcount-1]); 
}