2016-11-14 112 views
0

我有一個C語法問題,這讓我瘋狂。我已經定義了一些容器結構:C結構內動態數組內結構內的動態分配數組的語法

typedef struct AStruct { 
    int importantData1; 
    int importantData2; 
} A; 

typedef struct BStruct { 
    A* arr1;    // dynamic array of A structs 
} B; 

typedef struct CStruct { 
    B* arr2;    // dynamic array of B structs 
} C; 

正如你所猜測的,每個A結構體都保存着我程序的一部分數據。每個B結構都包含一個A的數組,每個C結構包含一個B的數組。我預計只需要一個C結構。我的C結構數據,以便總量將是:

total data in C == (num of B's) * (num of A's) 

棘手的部分是,我不知道有多少A和B的我需要在編譯的時候。這意味着我不能硬連線陣列大小;他們必須動態分配。

有一種方法可以做到這一點。這裏是我的笨拙嘗試:

void makeContainers(C* x, int numB, int numA){ 
    x->arr2 = (B*)malloc(numB * sizeof(B)); // allocate an array of empty B structs 
    B* Bptr; 
    int i; 
    for(i=0; i<numB; i++){ 
      Bptr = x->arr2[i];      // Bptr is one of the B's in C's arr2 
      Bptr = (A*)malloc(numA * sizeof(A)); // Allocate an array of empty A stucts 
    } 
} 

int main() { 
    C* bigContainer = (C*)malloc(sizeof(C)); // Allocate the C struct 
    makeContainers(bigContainer, 8, 8);   // populate C with B's and A's 

    return 0; 
} 

這在紙上看起來很棒...但是編譯器恨Bptr = x->arr2[i];線。 (在Linux上使用GCC編譯)這裏的錯誤:

[Linux]$ gcc -Wall setsInSets.c 
setsInSets.c: In function ‘makeContainers’: 
setsInSets.c:23:8: error: incompatible types when assigning to type ‘struct B *’ from type ‘B’ 
    Bptr = x->arr2[i]; // Bptr is one of the B's in C's arr2 
     ^

的 「從型B型結構乙」 部分混淆了我。不知道編譯器在這裏告訴我什麼。

而且...這是有點兒一個C 101型的問題,但我不能肯定我完全明白什麼makeContainers第一行()是做:

x->arr2 = (B*)malloc(numB * sizeof(B)); 

在這裏,我分配內存對於一系列B結構......但這是否意味着當這個命令結束時,我實際上有一堆「空的」B結構準備好了嗎?或者我只是放下內存,但內存本身只包含「垃圾」?換句話說,我是否必須走x->arr2陣列和malloc()單個B結構?

我知道這可能是一個重複的問題 - 但我仍然要求它,因爲我認爲這個問題的「動態數組結構內的結構」是一個非常具體的問題。

謝謝! -Pete

+0

'x-> arr2 [i]'評估爲一個'B'對象,而不是一個指針。也許你打算寫'Bptr = x-> arr2'? – Jezor

+1

[不要在C中投入malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar

+0

那些根本不是數組。它們是結構體,所以你不能做'x-> arr2 [i]'但是如果你想訪問,例如'importantData1',你實際上可以做'x-> arr2-> arr1-> importantData1' –

回答

3

x->arr2是指針到B結構

x->arr2[i]被解除引用一個元件陣列中即乙結構

要設置所需的結構的地址的指針陣列

B* Bptr = &(x->arry[i]); 

,或者更方便

B* Bptr = x->arry + i; 

我建議你在你的結構中寫入數組的大小,它可能會在稍後派上用場。

例如

typedef struct BStruct { 
    size_t elements;  // to know how many A structs 
    A* arr1; 
} B; 

編輯:

代碼

Bptr = x->arr2 + i;   // Bptr is one of the B's in C's arr2 
Bptr = malloc(numA * sizeof(A)); 

的這部分是沒有意義的,首先要將Bptr,然後將其分配到另一個地址。

+0

這非常非常清楚,謝謝。我的語法現在可用。將大小添加到結構中是一種天才,我已經實現了它。太好了! – Pete