2009-05-26 46 views
9

我需要通過長度應該是動態的互聯網傳輸數據包。C:動態大小結構的推薦樣式

struct packet 
{ 
    int id; 
    int filename_len; 
    char filename[]; 
}; 

問題是零長度數組不符合ISO標準。

應該用char filename[1];代替嗎?但那麼sizeof(struct packet)將不會返回正確的值了。

回答

6

經典問題。你可以簡單地處理它(並且注意,如果編譯器將結構尺寸向上舍入(這是我相信的),sizeof(foo)可能會超過一個),或者你可以這樣做:

struct packetheader { 
    int id; 
    int filename_len; 
}; 
struct packet { 
    struct packetheader h; 
    char filename[1]; 
}; 

這是煩人的(你必須使用h.id等),但它的工作原理。通常我只是將它作爲一個來處理,但上述可能稍微更具可移植性。

6

我想你應該看看現有的一些動態大小的結構示例,以便在此處獲得指導。我所知道的最好的例子是Win32中的TOKEN API。他們用這只是解決降到1雷蒙德陳宏ANYSIZE_ARRAY做了一個廣泛的博客文章,詳細說明究竟爲什麼他們做這樣

至於如失敗的sizeof操作。無論您爲動態大小的結構選擇何種解決方案,這都會失敗。 sizeof是編譯時操作,您將在運行時重新調整結構大小。它根本無法工作。

+0

與sizeof我的意思只是結構的大小,而不是動態字段,因爲當接收到UDP數據包時,我首先讀取包含動態字段大小的結構,然後讀取動態字段。 – codymanix 2009-05-26 14:48:49

4

我建議使用char filename[1]幷包含一個終止0字節。這樣一來,就可以malloc()正確的結構尺寸和避免一次性象這樣的錯誤:

ptr = malloc(sizeof(struct packet)+filename_len); 
strncpy(&ptr->filename, filename, filename_len); 

但接收器必須知道它需要讀取filename_len+1字節。

3

確實zero-length arrays不是標準的一部分。但是你的代碼片段中有一個靈活的數組,它是ISO C99標準的一部分。如果你可以使用C99,我會使用靈活的數組,如果不是jesup的建議可能是最好的。