2012-04-04 50 views
0

在子功能分配存儲器時,這是我的代碼,這對於由這些參數指定大小的矩陣分配空間,並返回指向在所說的基質:怪異分段故障在C

int **allocateSpace(int row, int col){ 
    int i; 
    int **a; 
    a = malloc(sizeof(int *) * row); 
    for(i = 0; i < row; i ++)            
     a[i] = malloc(sizeof(int) * col); 
    return a; 
}  

上面的代碼作品如預期。

然而,當我的代碼更改爲以下形式,我得到一個分段錯誤:

void allocateSpace(int **a, int row, int col){ 
    int i; 
    a = malloc(sizeof(int *) * row); 
    for(i = 0; i < row; i ++) 
     a[i] = malloc(sizeof(int) * col); 
} 

似乎從allocateSpace()函數返回時一樣,分配的內存被釋放(因爲我得到一個分段錯誤)。但爲什麼?我所做的只是爲給定的指針分配內存,並且全部在子功能中完成。

總結我的問題:爲什麼在第二段代碼中出現段錯誤? 非常感謝!

回答

6

因爲你需要在一個指針傳遞給一個指針的指針,以指定分配的內存:

void allocateSpace(int ***a, int row, int col){ 
    int i; 
    *a = malloc(sizeof(int *) * row); 
    for(i = 0; i < row; i ++) 
     (*a)[i] = malloc(sizeof(int) * col); 
} 

,並呼籲它,你將需要傳遞的int**地址:

int** ppData; 

allocateSpace(&ppData, 10, 10); 
+1

+1你剛剛在我*之前得到了答案,並且*舉了一個如何打電話的例子。 – JeremyP 2012-04-04 10:32:01

0

的問題是,你正在試圖改變這種狀況是按值傳遞一個指針:

void allocateSpace(int **a, int row, int col){ 
    // ... 
} 

int** a這裏通過(即,指針值被複制到堆棧以便將其用作函數參數)。

當你然後做

a = malloc(sizeof(int *) * row); 

你只改變複製指針的,一旦函數返回時,你的改變將被丟棄。

的解決方案是通過參考由以下的基準來傳遞指針,即

void allocateSpace(int ***a, int row, int col){ 
//... 
} 

和改變實際值:

*a = malloc(sizeof(int *) * row); 
0

在第二種情況下要修改的函數的參數a - 這是按值傳遞的本地副本。因此,如果您調用如下函數:allocateSpace(myptr,N,M)myptr將不會被修改 - 函數的本地副本將會被修改。因此,myptr包含調用之前包含的任何內容 - 可能是垃圾。您需要將函數參數更改爲:int ***a(哦,恐怖),然後在函數體中的每個引用a之前再添加一個*(取消引用op)。

將此與您想要在函數中修改簡單整數的情況進行比較 - 參數應爲int *,並且函數體中的賦值應該爲*a。同樣適用於此 - 需要額外的一級解除引用來實現您的目標。

0

在第二個函數中,int ** a通過value(指針)傳遞,因此函數中的更改不會影響調用者的函數。你必須通過引用傳遞這個值。