C C 中長度為0的陣列

2021-08-14 06:03:30 字數 1726 閱讀 1096

參考文獻:

近日在看專案中的框架**時,發現了了乙個奇特的語法:長度為0的陣列例如 

uint8_t buf[0];

我從未見過這樣的寫法,所以在網上查了查資料,了解並記錄下來.

在標準的c/c++中,長度為0的陣列是不被允許的,它算是乙個c/c++擴充套件,如果你的編譯器支援這個擴充套件,你就可以使用它.

vs系列編譯器不完全支援這個擴充套件,如果你這樣定義,多半會在編譯時出現這樣的警告:warning c4200: 使用了非標準擴充套件 : 結構/聯合中的零大小陣列,當 udt 包含大小為零的陣列時,無法生成複製建構函式或副本賦值運算子

gun編譯器完全支援這個擴充套件,你可以合法的宣告長度為0的陣列,但這種宣告的最典型的用法就是位於陣列中的最後一項,為了方便記憶體緩衝區的管理,例如:

struct

line;

在結構體中,長度為0的陣列不會占用儲存空間 ,在上述例子中 sizeof(line)=4

在申請記憶體空間時,緩衝區的空間可以和結構體的空間一起申請,一次操作就可以完成.例如

uint32_t length = 10

;struct line *pline = (struct line *)malloc(sizeof (struct line) +length);

pline->length = length;

上述**就動態地為結構體申請了長度(length)為10byte的緩衝區,而且由於是同一次malloc操作,緩衝區與結構體的記憶體位址是連續的,而且可以按照陣列下標訪問緩衝區元素,例如

for(uint32_t i = 0;i < pline->length;++i)

由於緩衝區與結構體的記憶體位址是連續的,在釋放記憶體的時候,只需要一次free操作.

綜上所述,比起在結構體中定義乙個指標指向另一片緩衝區位址的做法,使用長度為0的陣列有以下好處:

1->指標本身需要占用記憶體,而長度為0的陣列不需要

2->長度為0的陣列定義出的緩衝區可以和結構體處在同一片連續位址中,只要一次malloc操作和free操作.如果用指標,需要分別申請和釋放結構體內存和指標指向的記憶體塊,至少需要兩次以上的記憶體操作.

測試**:

編譯器:  gcc version 4.8.1 (tdm-2)

#include #include 

#include

struct

line;

int32_t main()

for (i = 0; i < pline->length; ++i)

//free(pline);

return0;

}

成功執行並列印結果:

sizeof(line)=4

i=0,contents[i]=0

i=1,contents[i]=1

i=2,contents[i]=2

i=3,contents[i]=3

i=4,contents[i]=4

i=5,contents[i]=5

i=6,contents[i]=6

i=7,contents[i]=7

i=8,contents[i]=8

i=9,contents[i]=9

press any key to

continue . . .

在vs2013中編譯執行上述**,除了會報警告 " warning c4200 " 外,程式也可以正確執行.

struct中長度為0的陣列用途與原理

在標準c和c 中,長度為0的陣列是被禁止使用的。不過在gnuc中,存在乙個非常奇怪的用法,那就是長度為0的陣列,比如array 0 很多人可能覺得不可思議,長度為0的陣列是沒有什麼意義的,不過在這兒,它表示的完全是另外的一層意思,這個特性是不可移植的,所以,如果你致力於編寫可移植,或者是稍稍需要跨平...

C語言長度為0的陣列

前面在看xen 的原始碼時,遇到了一段 如下所示 注意上面最後一行的 這裡定義了乙個長度為的陣列,這種用法可以嗎?為什麼可以使用長度為 0 的陣列?長度為 的陣列到底怎麼使用?這篇文章主要針對該問題進行簡單的講解。廢話不多說了,現在就開始。長度為的陣列在標準c和 c 中是不允許的,如果使用長度為 的...

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

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