2017-05-18 74 views
-2

未初始化的大小在程序陣列與內部結構體

#include<stdio.h> 

struct t { 
     char a[5]; 
     char b[]; 
     } temp; 

int main(){ 
     temp.b[0] = 'c'; 
     temp.b[1] = 'b'; 
     temp.b[2] = '\0'; 
     printf("Size of struct = %lu\n", sizeof(temp)); 
     printf("String is %s\n", temp.b); 

     printf("Address of temp = %p\n", &temp); 
     printf("Address of array a = %p\n", &(temp.a)); 
     printf("Address of b = %p\n", &(temp.b)); 
} 

與輸出

Size of struct = 5 
String is cb 
Address of temp = 0x601035 
Address of array a = 0x601035 
Address of b = 0x60103a 

在這個程序中,究竟是數組b被分配?多久了?這是一些未定義的行爲,只是在虛擬程序中取得成功,因爲我沒有做任何其他事情。運行到gdb中,我可以訪問一些初始化爲零的內存位置,這讓我懷疑它正在分配一些內存。

我的確有一個api,需要我將結構的一個元素格式化爲int a [] [SIZE],我對此感到困惑。

此外,爲什麼sizeof沒有考慮到至少從數組b的東西。我不確定它是否將其作爲數組或指針。

+1

http://stackoverflow.com/a/11734035/669576 –

+1

'b'是一個靈活的陣列成員;在C99中引入。 –

+1

你在這裏有什麼是未定義的行爲。上面提到的開放結構的東西只適用於混雜的東西。你有一個靜態結構。你正在註銷它的結尾 – pm100

回答

3

您使用它的方式是未定義的行爲。要回答您的即時問題,請使用靜態或自動存儲(在使用時),此成員的大小爲0。所以任何索引都是無效的。它「似乎」在您的實驗中工作,但請記住,不會執行任何邊界檢查。事實上,你正在做無效的寫入,你只是幸運的你的例子不會崩潰和燃燒。

這樣的構件僅允許作爲結構的最後構件和用於這是你可以用它來與動態存儲的原因:

struct t *temp = malloc(sizeof(struct t) + 5 * sizeof(char)); 

將分配的struct t的實例與temp->b作爲一個陣列char的大小5.

+0

請注意,它也可以與其他存儲類型一起使用,方法是與struct和char緩衝區進行聯合。但動態分配是最常見的用途。 –