數組下標爲0

長度爲0的數組——C語言的非標準用法之一 

在標準C和C++中,長度爲0的數組是被禁止使用的。不過在GNU C中,存在一個非常奇怪的用法,那就是長度爲0的數組,比如Array[0];很多人可能覺得不可思議,長度爲0的數組是沒有什麼意義的,不過在這兒,它表示的完全是另外的一層意思,這個特性是不可移植的,所以,如果你致力於編寫可移植,或者是稍稍需要跨平臺的代碼,這些Trick最好還是收起來的好。

在GNU的指南中,它是如此寫道:

struct line {
int length;
char contents[0];
};

//...ommit code here

{
struct line *thisline
   = (struct line *) malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
}

這個用法主要用於變長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)的方式釋放掉分配的內存。

ASSERT:除非必要,不要輕易使用這個功能,GNU C下可以編譯通過,所以你在使用vc++,那就不用嘗試了,編譯都無法通過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章