1. 程式人生 > >如何讓C語言函式返回一個二維陣列

如何讓C語言函式返回一個二維陣列

為了讓C語言函式返回一個二維陣列,有些人這樣定義函式:

int **foo(int rows, int columns)

然後在函式中費勁心機拼出來一個這樣的malloc語句:

int (*result)[columns] = (int (*)[columns])malloc(rows * columns * sizeof(int));

在函式內讀寫這個陣列發現很正常,等把陣列返回給呼叫函式後,再讀寫這個陣列就crash掉了。
原因其實很簡單,函式返回值型別是int **foo,而實際返回值型別是int (*bar)[columns],它們的區別就是foo[1] - foo[0] = sizeof(int *),而bar[1] - bar[0] = sizeof(int [columns])。把bar賦值給foo以後,訪問foo[1][0]會訪問到啥呢?首先要看foo[1]是個啥,foo[1] = *(foo + 1),那個1雖然看起來是1,但是實際加到foo上的大小實際上是foo指向元素的大小,如果說sizeof(int) = sizeof(int *) = 4的話,也就是foo值增加4,然後對這個地址取值,放到bar中取到了啥呢,實際上取出來的是bar[0][1],所以說,實際上foo[1] = bar[0][1],然而bar[0][1]並不是一個指標或者陣列,所以讀foo[1][0]就會crash掉。
正確的做法是這樣的:

int **result = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++)
{
    result[i] = (int *)malloc(columns * sizeof(int));
}

當然你也可以修改函式原型返回型別,但是那樣的話函式看起來就會比較費解一些。當然了,你也可以定義一個結構體,結構體裡面放一個數組,但是這樣做的缺陷就是大小需要固定,沒辦法根據輸入動態產生一個指定大小的結構體。
之前還寫過一篇相關的部落格,可以參考一下:http://blog.csdn.net/imred/article/details/45441457