2014-03-24 57 views
3

我試圖分配一個二維字符數組像ary[i][j]使用此代碼來訪問:c:動態分配2d char數組時出現問題?

#define stringmaxlen 20 

void do_alloc(char ***vals, int valscount){ 
    *vals = (char**) calloc(sizeof(char**), valscount); 
    int i = 0; 
    for (; i<valscount; i++) 
     *vals[i] = (char*) calloc(sizeof(char*), stringmaxlen); 
} 

int main(){ 
    //...... 
    char** ary; 
    do_alloc(&ary, 10); 
    strcpy(ary[0], "test"); 
    //...... 
} 

不幸的是,這個地方引起溢出,並計劃在執行中的錯誤,我得到了一些參考這裏用於動態分配:http://staff.science.nus.edu.sg/~phywjs/CZ1102/lecture20/sld014.htm

我想知道這裏有什麼問題以及如何解決問題,謝謝。

+0

您使用'calloc'的參數是相反的順序,從[這裏](http://www.cplusplus.com/reference/cstdlib/calloc/)和[there](http:// msdn.microsoft.com/en-us/library/3f8w183e.aspx);雖然我真的不知道這是否會導致錯誤的行爲。 – ThoAppelsin

+1

@ThoAppelsin在我知道的任何平臺上,參數到'calloc'的順序都是無關緊要的。 – cmaster

回答

7

您的運算符優先順序錯誤:*vals[i]的計算結果爲*(vals[i]),而不是(*vals)[i]。詳細信息請參見http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

修復方法是將*vals[i]更改爲(*vals)[i]

另外,分配*vals[i] = (char*) calloc(sizeof(char*), stringmaxlen);是錯誤的。它分配太多的內存,因爲它分配的空間爲stringmaxlen指針,但你只需要stringmaxlen個字符。

+0

是啊!就是這樣,現在問題已經解決了,精確度很重要!謝謝你,兄弟! – user3457200

3

我想添加以下內容給cmaster的答案。

而不是

*vals = (char**) calloc(sizeof(char**), valscount); 

使用

*vals = (char**) calloc(sizeof(char*), valscount); 

而不是

(*vals)[i] = (char*) calloc(sizeof(char*), stringmaxlen); 

使用

(*vals)[i] = (char*) calloc(sizeof(char), stringmaxlen); 

在第一種情況下,分配的內存大小不變,因爲sizeof(char**)sizeof(char*)相同。然而,第二種情況並非如此。 sizeof(char)爲1,而sizeof(char*)較大 - 對於32位硬件爲4,對於64位硬件爲8。

更重要的是,它闡明瞭這個意圖 - 你想爲stringmaxlen字符分配內存,而不是stringmaxlen指向字符的指針。

+1

您可以通過使用習慣用語來避免這些錯誤:'P = calloc(N,sizeof * P);' '* vals = calloc(valscount,sizeof ** vals);'等等 –

+0

@MattMcNabb好習慣用法。 –