在看Linux內核的路由代碼時,發現有以下的結構體定義:c++
1 struct fib_table { 2 unsigned char tb_id; 3 unsigned tb_stamp; 4 int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); 5 int (*tb_insert)(struct fib_table *table, struct rtmsg *r, 6 …… 7 void (*tb_select_default)(struct fib_table *table, 8 const struct flowi *flp, struct fib_result *res); 9
10 unsigned char tb_data[0]; 11 };
其中,tb_data數組的長度爲0,通過百度(blog.csdn.net/zhaqiwen/article/details/7904515)得知:長度爲的數組在標準c和c++中是不容許的,若是使用長度爲的數組,編譯時會產生錯誤,提示數組長度不能爲,但在GNUc中,這種用法倒是合法的。
對於長度爲0的數組,在gcc手冊中,有以下一段代碼片斷:數組
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length); thisline->length = this_length;
這段代碼的主要含義是定義了一個結構體,並對其進行初始化。零長數組有如下幾個特色:函數
1,不佔內存空間,上面結構體的第二個成員變量contents[0]事實上是不佔內存空間的,所以整個結構體的長度sizeof(struct line)爲4;this
2,零長數組指向的內存區域與其所在結構體佔用的內存區域是連續的,當採用malloc爲thisline指向的內容申請內存空間時,如上所示,申請了一段長度爲結構體長度加可變長度的內存空間給結構體類型的指針,這時contents就指向申請的可變長度的內存空間。因爲是一次申請的,因此這段可變長度的內存空間和前面的結構體長度的內存空間是連續的;spa
3,零長數組指向的內存能夠採用數組的方式訪問(指針也是能夠的,沒有什麼差異)。.net
4,統一釋放,對於整個結構體,當再也不使用時,能夠使用free函數一次性對其進行釋放,而沒必要像指針那樣分別釋放。指針