變長結構體是由gcc擴展的一種技術,它是指其最後一個成員的長度不固定(flexible array member,也叫柔性數組),先來看一個簡單的例子:數組
#include <stdlib.h> #include <stdio.h> #pragma pack(1) typedef struct { int a; char b[10]; char *vector; } cq; #pragma pack() int main() { cq *a = malloc(sizeof(cq)); char str[] = "hello"; a->vector = malloc(sizeof(str)); memcpy(a->vector, str, sizeof(str)); printf("%s\n", a->vector); // "hello" printf("%d\n", sizeof(cq)); // 22 free(a->vector); free(a); return 0; }
這段代碼中,結構體cq中的成員vector是一個指針,你在分配內存緩衝區時,就必須分配結構體一次,而後再分配結構體內的指針一次,(而此時分配的內存已經與結構體的內存不連續了,因此要分別管理即申請和釋放)。ide
而若是使用數組,那麼只須要一次就能夠所有分配出來,(見下面的例子),反過來,釋放時也是同樣,一次釋放。而使用指針,得先釋放結構體內的指針,再釋放結構體。還不能顛倒次序。其次,就是分配一段連續的的內存,減小內存的碎片化。flex
#include <stdlib.h> #include <stdio.h> #pragma pack(1) typedef struct { int a; char b[10]; char vector[0]; // 可變數組 } cq; #pragma pack() int main() { char str[] = "hello"; cq *a = malloc(sizeof(cq) + sizeof(str)); // decide amount used memcpy(a->vector, str, sizeof(str)); printf("%s\n", a->vector); // "hello" printf("%d\n", sizeof(cq)); // 14 free(a); return 0; }
例子中,打印出的結構體長度是14(爲成員a和b的長度之和),——變長數組vector不佔結構體的空間!this
可見,變長結構體是能讓咱們在分配時再決定其大小,而不是在定義時就要固定其數組長度。spa
可變數組的一種更通用的用法是用一個成員指明變長數組的長度,方便在其餘地方讀取數組內容。翻譯
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length); thisline->length = this_length;
最後,轉述一段C99標準(draft N1570)對這個問題的描述,本人英文很爛,就不翻譯了。指針
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply. However, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.code
參考:blog
http://stackoverflow.com/questions/11733981/what-is-the-purpose-of-a-zero-length-array-in-a-struct內存