2012-11-04 81 views
1

我一直在爲電磁仿真中的課程寫作一段代碼,並且遇到了問題。我決定通過將原始計算擴展到10^8個元素的真正大網格來做一些額外的工作,所以現在我必須使用malloc()。在結構中使用指向動態2D數組的指針

到目前爲止,這麼好,但由於我更喜歡​​將代碼保存在庫中,然後使用編譯器的內聯選項進行編譯,所以我需要一種在函數間傳遞信息的方法。所以,我開始使用結構來跟蹤網格的參數,以及指向信息數組的指針。我用如下方法定義結構:

typedef struct { 
    int height; 
    int width; 
    int bottom; //position of the bottom node 
    unsigned int*** dat_ptr;//the pointer to the array with all the data 
    } array_info; 

其中指向無符號整型的三指針是指向二維數組的指針。我必須這樣做,否則它是通過值傳遞的,我不能在函數內改變它。

現在,當我嘗試用下面的函數的結構分配內存:

void create_array(array_info A)//the function accepts struct of type "array_info" as argument 
{ 
    int i; 

    unsigned int** array = malloc(sizeof(*array) * A.height);//creates an array of arrays 
    for(i = 0; i<A.height; ++i) 
    { 
     array[i] = malloc(sizeof(**array) * A.width);//creates an array for each row 
    } 
    *A.dat_ptr=array;//assigns the position of the array to the input pointer 
} 

我在執行操作時出現段故障。我看不到爲什麼:sizeof(* A.dat_ptr)與sizeof(array)相同。因此,在最壞的情況下,我應該在線下的某個地方弄到亂碼,而不是在任務欄中,對嗎?

+2

爲什麼一個二維數組的三重指針? –

+0

如果我將它用作雙指針,則指針本身的值不能在函數的作用域之外改變。也就是說,當我將整個結構傳遞給另一個函數時,我只能編輯數組的內容,而不是它在內存中的位置,這正是我想要用create_array所做的。 – MechaPrime

+1

@ user1798476:這是不正確的。將ref傳遞給** ptr ...或者更好的是從函數返回整個結構體。 –

回答

3

您可能需要從函數返回array_info結構(更正常)或(通常)將指針傳遞給array_info結構,以便您所做的更改會影響調用函數中的值。

typedef struct 
{ 
    int height; 
    int width; 
    int bottom; 
    unsigned int **dat_ptr; // Double pointer, not triple pointer 
} array_info; 

void create_array(array_info *A) 
{ 
    unsigned int **array = malloc(sizeof(*array) * A->height); 
    for (int i = 0; i < A->height; ++i) 
     array[i] = malloc(sizeof(**array) * A->width); 
    A->dat_ptr = array; 
} 

我假設你做了一些內存分配的檢查;雖然,邏輯的地方是這個功能。從部分故障中恢復是很煩瑣的(但是如果你打算從函數中返回而不是從程序中退出,這是必要的)。

void create_array(array_info *A) 
{ 
    unsigned int **array = malloc(sizeof(*array) * A->height); 
    if (array != 0) 
    { 
     for (int i = 0; i < A->height; ++i) 
     { 
      if ((array[i] = malloc(sizeof(**array) * A->width)) == 0) 
      { 
       for (int j = 0; j < i; j++) 
         free(array[j]); 
       free(array); 
       array = 0; 
       break; 
      } 
     } 
    } 
    A->dat_ptr = array; 
} 

調用函數知道,如果dat_ptr成員是從create_array()返回NULL函數失敗。提供成功/失敗返回值可能會更好。

我使用的是C99,所以調用代碼可能是:

array_info array = { .height = 10, .width = 20, .dat_ptr = 0 }; 
create_array(&array); 
if (array->dat_ptr == 0) 
    ...error handling... 

注意,在create_array()代碼可能需要檢查一個空指針,爲負或零寬度或高度。我不清楚bottom元素應該包含什麼,所以我沒有初始化它,這給了我一半使用指定初始值設定項的藉口。您也可以非常清楚地編寫初始化程序,而不使用指定的初始化程序。

+0

+1 ........................... –

+0

太棒了!我沒有任何言語表達我的感激之情:)我幾個小時一直在抨擊我的頭......現在非常感謝你:) – MechaPrime