簡體   English   中英

奇怪的可變大小的數組聲明

[英]Strange variable-sized array declaration

閱讀此Skip List實現,我遇到了這個代碼片段:

typedef struct nodeStructure{
    keyType key;
    valueType value;
    node forward[1]; /* variable sized array of forward pointers */
    };

對我來說,似乎forward[1]表示一個元素數組。 並且注釋稱它為可變大小的數組

我是否誤解了某些內容,或者這只是我正在閱讀的來源中的一個錯誤?

它被稱為struct hack 它是C99中引入的靈活陣列成員形式。

過去曾使用它來模仿結構的最后一個成員中的變量數組,但它不是C中嚴格符合的結構。

這是C中的程序范例,有時您會看到。 分配結構時,您將分配sizeof(struct nodeStructure + numNodes * sizeof(node))。

這允許您為結構提供多個前向節點,即使它只被聲明為具有一個。 這是一個丑陋的黑客,但它的工作原理。

通常,當您執行此操作時,還會有一個名為“count”的字段,以便您知道節點后面有多少額外條目。

這是舊的C編譯器(C99)之前常用的技巧:讓你解引用元素過去年底編譯器forward的聲明長度時,這是最后一個元素struct ; 然后你可以為其他node元素malloc足夠的內存,如下所示:

nodeStructure *ptr = malloc(sizeof(nodeStructure)+4*sizeof(node));
for (int i = 0 ; i != 5 ; i++) { // The fifth element is part of the struct
    ptr->forward[i] = ...
}
free(ptr);

該技巧允許您在結構中嵌入可變大小的數組,而無需單獨的動態分配。 另一種解決辦法是宣布node *forward ,但隨后你需要mallocfree從它分開nodeStructure ,不必要增加一倍數量malloc S和潛在地增加內存碎片:

以下是上述片段在沒有黑客的情況下的外觀:

typedef struct nodeStructure{
    keyType key;
    valueType value;
    node *forward;
};

nodeStructure *ptr = malloc(sizeof(nodeStructure));
ptr->forward = malloc(5*sizeof(node));
for (int i = 0 ; i != 5 ; i++) {
    ptr->forward[i] = ...
}
free(ptr->forward);
free(ptr);

EDIT (響應Adam Rosenfield的評論):C99允許您定義沒有大小的數組,如下所示: node forward[]; 這稱為靈活陣列成員 ,它在C99標准的6.7.2.1.16部分中定義。

數據結構實現很可能是針對C90標准編寫的,C90標准沒有靈活的陣列成員 (在C99中添加)。 那時,通常在結構的末尾使用1或甚至0大小的(*)數組來允許訪問那里動態可變數量的元素。

注釋不應解釋為C99樣式的可變長度數組; 此外,在C99中,成員forward的慣用和符合標准的定義是node forward[]; 然后將具有這樣的成員的諸如struct nodeStructure類型稱為不完整類型 您可以定義指向它的指針,但是您不能定義此類型的變量或取其大小, node forward[0]node forward[1]允許的所有操作,盡管這些操作可能與程序員的意圖不匹配。

(*)標准禁止0大小的數組,但GCC接受這些作為正確使用的擴展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM