C語言長度為0的陣列

2021-06-15 04:23:51 字數 1882 閱讀 3819

前面在看xen

的原始碼時,遇到了一段**,如下所示:

注意上面最後一行的**,這裡定義了乙個長度為的陣列,這種用法可以嗎?為什麼可以使用長度為

0 的陣列?長度為

的陣列到底怎麼使用?

……這篇文章主要針對該問題進行簡單的講解。廢話不多說了,現在就開始。

長度為的陣列在標準c和

c++中是不允許的,如果使用長度為

的陣列,編譯時會產生錯誤,提示陣列長度不能為

。但在gnuc

中,這種用法卻是合法的。它的最典型的用法就是位於陣列中的最後一項,如上面所示,這樣做主要是為了方便記憶體緩衝區的管理。如果你將上面的長度為

的陣列換為指標,那麼在分配記憶體時,需採用兩步:首先,需為結構體分配一塊記憶體空間;其次再為結構體中的成員變數分配記憶體空間。這樣兩次分配的記憶體是不連續的,需要分別對其進行管理。當使用長度為

的陣列時,則是採用一次分配的原則,一次性將所需的記憶體全部分配給它。相反,釋放時也是一樣的。

對於長度為的陣列,在

gccstruct line ;

struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);

thisline->length = this_length;

這段**的主要含義是定義了乙個結構體,並對其進行初始化,上面結構體的第二個成員變數contents[0]

事實上是不佔記憶體空間的,因此整個結構體的長度

sizeof(struct line)為4

。當採用

malloc

為其申請記憶體空間時,如上所示,申請了一段長度為結構體長度加可變長度的記憶體空間給結構體型別的指標,這時

contents

就指向申請的可變長度的記憶體空間。由於是一次申請的,所以這段可變長度的記憶體空間和前面的結構體長度的記憶體空間是連續的。對於這段可變長度的記憶體空間,可以採用陣列的方式對其進行訪問。對於整個結構體,當不再使用時,可以使用

free

函式一次性對其進行釋放,而不必像指標那樣分別釋放。

下面舉例進行說明:

#include 

#include 

#define length 10

struct test1

__attribute((packed));

struct test2

__attribute((packed));

struct test3

__attribute((packed));

int main()

printf("\n\n"); 

var3=(struct test3*)malloc(sizeof(struct test3));

var3->a=3;

(var3->b)[0]=3;

printf("var3->a=%d,(var3->b)[0]=%d\n",var3->a,(var3->b)[0]);

free(var1->b);

free(var1);

free(var2);

free(var3);}

這段程式的執行結果如下圖所示:

從上面的結果可以看出: l 

長度為的陣列並不占有記憶體空間,而指標方式需要占用記憶體空間。

l 對於長度為陣列,在申請記憶體空間時,採用一次性分配的原則進行;對於包含指標的結構體,才申請空間時需分別進行,釋放時也需分別釋放。

l 對於長度為的陣列的訪問可採用陣列方式進行。

C C 中長度為0的陣列

參考文獻 近日在看專案中的框架 時,發現了了乙個奇特的語法 長度為0的陣列例如 uint8 t buf 0 我從未見過這樣的寫法,所以在網上查了查資料,了解並記錄下來.在標準的c c 中,長度為0的陣列是不被允許的,它算是乙個c c 擴充套件,如果你的編譯器支援這個擴充套件,你就可以使用它.vs系列...

c語言宣告長度0的陣列

參考 c語言結構體裡的成員陣列和指標 1 char s 0 和 char a比較 void zero arr ptr void char s 0 char a null 由下面的結果可以得出 零長度陣列所佔記憶體空間為0,指標佔記憶體空間為4 s和 s的結果一樣,a獲取a指向的位址,a獲取去自身的位...

長度為0的字元陣列的賦值

結構體格式如下 struct ss t 需要給結構體中的msg賦值,由於msg的長度為0,直接賦值時程式提示賦值錯誤,經過處理之後,可以使用以下方式賦值 int totallen int command char msg 123456 int testlen sizeof msg char buf ...