2009-11-30 124 views
4

下面的代碼編譯,但立即崩潰的原因是明顯的其他人,但不是我。我似乎無法理解,誰能告訴我如何解決這個問題。Malloc指向指向結構數組的指針參考

*array_ref[2] = array[0]; 
*array_ref[3] = array[1]; 

它每次都在那部分上崩潰。

typedef struct test { 
    char *name; 
    char *last_name; 
} person; 



int setName(person ** array, person ***array_ref) { 

    *array = malloc (5 * sizeof(person)); 
    *array_ref= malloc(5 * sizeof(person*)); 

    array[0]->name = strdup("Bob"); 
    array[1]->name = strdup("Joseph"); 
    array[0]->last_name = strdup("Robert"); 
    array[1]->last_name = strdup("Clark"); 


*array_ref[2] = array[0]; 
*array_ref[3] = array[1]; 


    return 1; 
} 



int main() 
{ 
    person *array; 
    person **array_r; 

    setName(&array,&array_r); 

    printf("First name is %s %s\n", array[0].name, array[0].last_name); 
    printf("Second name is %s %s\n", array_r[3]->name, array_r[3]->last_name); 

    while(1) {} 
    return 0; 
} 
+3

在你的代碼有bug的情況下,特別是當bug是實際崩潰並且每次都發生時,通常應該做的事情是試圖將其縮小到最少量的代碼。 這樣可以讓其他人更容易在查看代碼時發現錯誤,更重要的是,讓您更容易理解導致崩潰的原因。 – 2009-11-30 00:30:10

+0

@Edan,在這種情況下,我不會說這是個問題。這裏沒有太多的代碼,問題很明顯。 – 2009-11-30 00:33:29

+0

+1 Edan。縮小這個範圍以刪除'array_ref'可以澄清問題,並且肯定會幫助ZPS理解它。 – 2009-11-30 00:39:50

回答

6

運算符[]比一元運算符operator*的優先級高。因此,這樣的:

*array_ref[2] = array[0]; 
*array_ref[3] = array[1]; 

實際上意味着:

*(array_ref[2]) = array[0]; 
*(array_ref[3]) = array[1]; 

類型是正確的在這裏,這就是爲什麼它編譯。但從你的代碼很明顯,你的意圖實際上是:

(*array_ref)[2] = array[0]; 
(*array_ref)[3] = array[1]; 

所以只需使用括號。

+0

記住'array [1]'沒有被分配:)。 – 2009-11-30 00:56:20

1

您爲array_ref指針分配了空間,但沒有爲它們指向的內容分配空間。

+0

他將它們指向分配的對象,這不是問題。 – 2009-11-30 00:33:58

1

嘗試的setName)改變以下(

*array_ref[2] = array[0]; 
*array_ref[3] = array[1]; 

*(*array_ref+2) = array[0]; 
*(*array_ref+3) = array[1]; 

這工作。

1

array[1]->name是你的問題。這應該是(*array)[1].name。注意兩者如何不等價。除了[0]之外,所有類似用途都有相同的問題,它意外地做了正確的事情。

請記住,array,函數參數不是你的數組,它是一個指向你的數組的指針。

1

在這樣的功能我更喜歡這樣的代碼:

int setName(person ** out_array, person ***out_array_ref) { 
    person* array = malloc(5 * sizeof(person)); 
    person** array_ref = malloc(5 * sizeof(person*)); 
    array[0].name = strdup("Bob"); 
    array[1].name = strdup("Joseph"); 
    array[0].last_name = strdup("Robert"); 
    array[1].last_name = strdup("Clark"); 
    // I'm guessing this was your intent for array_ref, here: 
    array_ref[2] = &array[0]; 
    array_ref[3] = &array[1]; 

    *out_array = out_array; 
    *out_array_ref = array_ref; 
    return 1; 
} 

注意,此捕獲兩個array[1]->name如由Roger佩特指出,和*array_ref[2] = array[0]如帕維爾注意到(幾乎) - 其溶液(* ARRAY_REF)[2 ] =數組[0]從未分配的person*array[1]分配 - 兩者都很難注意到額外的解除引用。

當然,我主要是這樣做的,因爲我使用C++,這增加了異常安全性;)。