2010-09-06 112 views
0

我有一個類似的問題here關於分配和初始化一個指向結構的子函數。不幸的是,我無法擴展我在那裏初始化結構體的數組的良好解決方案。 第一個元素是OK,但第二個(以及所有後續)元素是零/ NULL。在子函數中分配和初始化結構數組

這是一個註釋示例。也許有人可以幫我...

#include <stdio.h> 
#include <stdlib.h> 

typedef struct {int n;} mystruct; 

void alloc_and_init_array(mystruct **s) 
{ 
    // create an array containing two elements 
    *s = calloc(sizeof(mystruct), 2); 
    (*s[0]).n = 100; 
    (*s[1]).n = 200; 
} 

int main(void) 
{ 
    mystruct *s; // only a pointer. No memory allocation. 
    alloc_and_init_array(&s); 

    printf("1st element: %d\n", s[0].n); // here I get 100, that's OK 
    printf("2nd element: %d\n", s[1].n); // here I get 0. Why? 

    return 0; 
} 

回答

2

你需要一些括號:

((*s)[1]).n = 200; 
^ extra parentheses required 

下標([])具有比間接(*),所以沒有它首先應用於括號更高的優先級。

您需要解除引用s以獲取其指向的數組,然後訪問索引爲1的元素。

1

alloc_and_init_array括號內錯誤的地方。

s是一個指向結構數組的指針。所以*s是結構數組。因此(*s)[0](*s)[1]將分別給出該數組中的第一個和第二個結構。

因此,兩行應爲:

(*s)[0].n = 100; 
(*s)[1].n = 200; 
1

你調用未定義的行爲,[]的優先級高於*。你會想:

(*s)[0]).n = 100; 
(*s)[1]).n = 200; 
+0

謝謝大家,夥計們!無奈之下,我開始使用類似「* ptr + sizeof(mystruct)* i」的東西。您的解決方案非常棒。 – ClosedID 2010-09-06 22:18:07

1

至於二者的清晰度一般規則,避免後面的*運營商圍繞優先發展的必然問題,我會做這樣的事情:

void alloc_and_init_array(mystruct **s) 
{ 
    mystruct *p; 
    // create an array containing two elements 
    p = calloc(sizeof(mystruct), 2); 
    if (p) { 
     // initialize it if creation succeeded. 
     p[0].n = 100; 
     p[1].n = 200; 
    } 
    *s = p; 
} 

一我寫的細微差別在於,如果對calloc()的調用失敗,我不會無意中取消引用NULL指針。由於s必須爲非NULL,因此我會試着將assert(s)放在函數的頂部附近以記錄該錯誤並捕獲不可發生的錯誤。