2015-05-14 125 views
4

我寫了下面的C函數,它在必要的內存分配後返回一個雙指針。C內存分配和釋放

// integer double pointer to 2d array 
void** idp_to_2d (int rows , int cols) { 
    int i ; 
    void **est = malloc (rows * sizeof (int*)) ; 
    for (i = 0 ; i <= rows ; i ++) 
     est[i] = malloc (cols * sizeof (int)) ; 
    return est ; 
} 

然後我收到使用下面的代碼this指針從main()

int **est = (int**) idp_to_2d (rows , cols) ; 

它工作正常,我可以像est[i][j]意味着內存索引被正確分配。

現在我釋放內存中main()使用下面的代碼:

int i ; 
for (i = 0 ; i <= rows ; i ++) 
    free (est[i]) ; 
free (est) ; 

現在,我得到雙重釋放或腐敗錯誤。

我的編譯器GCC 4.9.2OS的Ubuntu 15.04(64位),我使用NetBeans IDE的8.0.2

+5

用[*未定義行爲*](http://en.wikipedia.org/wiki/Undefined_behavior)的問題是,它可能會* *似乎工作沒關係,和你有不確定的行爲,當你走超出分配內存的界限。 –

回答

11

您的循環是錯誤的 - 你迭代一個太多行 - 變化:

for (i = 0 ; i <= rows ; i ++) 
       ^^^ 

到:

for (i = 0 ; i < rows ; i ++) 
       ^^^ 

同時在malloc環路和free循環。


此外,雖然它不是這樣的錯誤,你應該改變:

void** idp_to_2d(... 

到:

int** idp_to_2d(... 

當然:

void **est = malloc(... 

到:

int **est = malloc(... 

因爲函數返回int **而不是void **。 (真的是在你的任何代碼的使用void **沒有意義的。)

您也可以刪除多餘的(和潛在的危險)的返回值的演員,所以:

int **est = (int**) idp_to_2d (rows , cols) ; 

也只是:

int **est = idp_to_2d (rows , cols) ; 
+1

你甚至不應該在C中使用void指針 –

+0

@ErikW:很好。 –

+0

@ErikW:'void ** est;'沒有定義一個'void'指針。 – alk