2012-03-22 69 views
4

在參照GCC's Zero Length Array說明:可變數組成員(零長度陣列)

這是的情況下特別有用,當一個結構爲可變長度對象的報頭。這正是我的情況。此外,我關心的是我的結構在堆中的一致性。

在這種情況下,我仍然不明白零長度數組有什麼用處。它們與這種特殊情況有什麼關係?

編輯:

難道我可以把儘可能多的「數據」,因爲我想在那裏?

+0

http://stackoverflow.com/search?q=struct+hack+[c]&submit=search – dmckee 2012-03-22 04:25:34

+0

如果可以避免使用此gcc擴展名,請不要使用此gcc擴展名。自C99以來,靈活數組的正確語法是'''struct'的最後一個成員'[]'的一個空括號'[]',而不是'[0]'。 Gcc也支持這種表示法。 – 2012-03-22 07:22:16

回答

2

基本上它允許你具有這樣的結構,並在後面的可變長度數組:

struct X { 
    int first; 
    int rest[0]; 
}; 

由於C並不真正關心您正在訪問元素超出數組的末尾,你剛開始大小爲0的數組,然後分配足夠的存儲器來處理然而,許多元件實際上要:

struct X *xp = (struct X *)malloc(sizeof(struct X)+10*sizeof(int)); 
xp->rest[9] = 0; 
+0

嗯 - 所以它真的與這兩個問題有關。 – darksky 2012-03-22 04:25:16

+2

好的解釋,但只是不使用語法'[0]'(這是一個gcc擴展名),但'']'(這是C99和gcc支持)或'[1]''哪至少給你定義的行爲。 – 2012-03-22 07:24:32

0

存儲器從malloc(),你將分配給一個指向與該零長度陣列構件的結構返回將是aligne d內存......這是C99規範所要求的。因此,通過malloc()從堆中分配的內存不會覆蓋具有零長度數組的結構。

如果遇到麻煩,可能會嘗試將結構覆蓋在來自打包或非傳統對齊數據源(例如文件頭,內存映射硬件接口)的內存中的某個原始緩衝區上,等等。在這些情況下,使用零長度數組來處理可變長度數據可能是一個壞主意,因爲數據可能不會根據平臺的默認對齊參數進行對齊,因此抵消陣列將不會產生正確的結果。

+0

我實際上實現了'malloc()',這就是爲什麼我自己擔心對齊。 – darksky 2012-03-22 04:29:50

+0

你是如何通過'mmap'實現'malloc'的?在某些時候,你將不得不從操作系統請求內存......內存將對齊。非傳統的對齊內存將像打包或「原始緩衝」數據源,內存映射硬件接口等。當我說「非傳統」時,我指的是即使緩衝區可能由一個'int',一個'char'等組成,你不能簡單地將一個包含這些元素的'struct'覆蓋在緩衝區上,並且不希望編譯器添加的填充符干擾覆蓋操作。 – Jason 2012-03-22 04:32:40