2013-05-29 27 views
0
typedef struct 
{ 
    int blah; 
    int bleh; 
} Foo; 

typedef struct 
{ 
    int a; 
    int b; 
    Foo* arr[]; 
} Bar; 

int main(int argc, char **argv) 
{ 
    Bar* bar = malloc(sizeof(Bar) + sizeof(Foo) * 5); 
    Foo foo1 = bar->arr[0]; 
    return 0; 
} 

在分配foo1的行上,我得到「無效初始值設定項」。如果我將其類型更改爲Foo*,它會進行編譯。但如果我做foo1->blah = 3,程序崩潰。爲什麼gcc說這是一個「無效的初始值設定項」?

爲什麼數組元素的類型爲Foo*而不是Foo?爲什麼程序崩潰?

+1

'爲什麼數組元素Foo *'的類型 - 當然,因爲您聲明它們是與'Foo * arr []' –

回答

3

arrFoo*數組所以你不能的arr的元素賦值給一個Foo這裏:

Foo foo1 = bar->arr[0]; 

的第二個問題是,即使你是爲arr分配內存正常,你需要初始化每個pointer另外,您正在解引用一個未初始化的指針,該指針是未定義的行爲。

如果你想的Foo數組那麼這就是你想要的東西:

typedef struct 
{ 
    int a; 
    int b; 
    Foo arr[]; 
} Bar; 

那麼你的代碼的其餘部分並沒有改變。

這是使用flexible array membersC99介紹和答案在這裏討論如何分配和正確釋放。

1

Foo* arr[]是一個指針數組,所以bar->arr[0]是一個指針。

這工作得很好:

Foo* foo1 = bar->arr[0]; 

要創建的Foo一個對象,你可以使用下列之一

Foo bar1 = *bar->arr[0] // or **bar->arr; though this may be less clear 
2

類型數組元素的是Foo *,因爲這是你到底如何申報他們。聲明Foo* arr[]代表一組Foo *元素。爲什麼你期望的元素是Foo,當你在聲明中明確說Foo *

更改foo1的類型爲Foo *看起來像一個沒有多大意義的隨機變化。你想做什麼 - 這是你應該首先回答的問題。 Bar最後需要什麼樣的陣列? Foo arr[]Foo *arr[]

根據您的malloc來判斷,看起來您想要在Bar的末尾聲明一個Foo元素的數組。如果是這樣,你必須將數組聲明更改爲Foo arr[]

相關問題