C語言的零長陣列

2021-07-14 04:26:56 字數 1584 閱讀 4499

在標準 c 或者 c++ 中由於不支援 0 長度的陣列,所以 int array[0]; 這樣的定義是非法的。不過有些編譯器的擴充套件功能支援 0 長度的陣列。

在 c 中,0 長度的陣列的主要用途是用來作為結構體的最後乙個成員,然後用它來訪問此結構體物件之後的一段記憶體(通常是動態分配的記憶體)。由於其非標準性,在程式中盡量避免使用 0 長度的陣列。作為替換,可以使用 c99 標準中的不完整陣列來替換 0 長度的陣列定義。如:

code:

struct x ;

>> 但是我的如下**是能順利編譯且不出警告和錯誤,而且能執行的啊

>> int array[0]

>> *array = 1;

程式中可能出現的錯誤有多種。一是語法錯誤,這類錯誤很容易在編譯階段檢查出來。除此之外,還有一類錯誤在編譯階段不能或者很難檢查出來,這類錯誤被稱為「無定義」,其結果是不確定的。

上面的**中因為有越界訪問陣列這一錯誤存在,所以它的行為(執行的結果)是無定義的。

應用比如:

code:

struct a ;

struct a *p;

int n = 100, i;

p = malloc(sizeof(struct a) + n);

for (i = 0; i < n; ++i)

p->data[i] = 1;

摘自:在gnu的指南中,它是如此寫道:

struct line ;

//...ommit code here

這個用法主要用於變長buffer,struct line的大小為4,結構體中的contents[0]不占用任何空間,甚至是乙個指標的空間都不佔,contents在這兒只是表示乙個常量指標,這個特性是用編譯器來實現的,即在使用thisline->contents的時候,這個指標就是表示分配記憶體位址中的某塊buffer,比如malloc (sizeof (struct line) + this_length)返回的是0x8f00a40,thisline->contents指向的位置就是(0x8f00a40 + sizeof(struct line)),而這兒sizeof(struct line)僅僅是乙個int的四位元組。

對於這個用法,我們定義的結構體指標可以指向任意長度的記憶體buffer,這個技巧在變長buffer中使用起來相當方便。可能有朋友說,為什麼不把最後的contents直接定義為乙個指標呢?這兒的差別是這樣的,如果定義為乙個指標,它需要占用4bytes,並且在申請好記憶體後必須人為賦位址才可以。如果使用這個用法,這個常量指標不占用空間,並且無需賦值。

但是,方便並不是絕對的,在釋放分配的記憶體的時候,由於函式free會認為*thisline 只是指向乙個4位元組的指標,即只會釋放length的空間,而對於後面佔據大頭的buffer卻視而不見,這個就需要人為干預;而對於後面的宣告指標的方式,則可以直接用free(thisline->contents)的方式釋放掉分配的記憶體。(這地方說的不明白,讓我理解之後,感覺此話是錯誤的。)

——>如果將零長陣列array換成指標*array來使用的話,指標必須重新分配一段記憶體之後才能使用,那麼當想要用socket傳送結構體指標的時候,並不會將指標array申請的記憶體傳送過去,因為是不連續的,所有接受socket傳送來的資料後,會發現該資料並不是自己想要的。

C語言的零長陣列

在標準 c 或者 c 中由於不支援 0 長度的陣列,所以 int array 0 這樣的定義是非法的。不過有些編譯器的擴充套件功能支援 0 長度的陣列。在 c 中,0 長度的陣列的主要用途是用來作為結構體的最後乙個成員,然後用它來訪問此結構體物件之後的一段記憶體 通常是動態分配的記憶體 由於其非標準...

Linux c 零長陣列

1 零長陣列 gnu c允許宣告長度為零的陣列,但它只能被用於結構體的最後乙個成員。例項 include include typedef struct postpos struct line int main void printf sizeof struct line d n sizeof str...

c語言零長陣列及對陣列名的理解

在標準c 和c 中0 長陣列如 chararray 0 是不允許使用的,因為這從語義邏輯上看,是完全沒有意義的。但是,gun中卻允許使用,而且,很多時候,應用在了變長結構體中,如 structpacket 首先對 0長陣列做乙個解釋 用途 長度為0的陣列的主要用途是為了滿足需要變長度的結構體。用法 ...