(轉)C語言中長度為0的數組


前面在看Xen的源碼時,遇到了一段代碼,如下所示:

注意上面最后一行的代碼,這里定義了一個長度為的數組,這種用法可以嗎?為什么可以使用長度為0 的數組?長度為的數組到底怎么使用?……這篇文章主要針對該問題進行簡單的講解。廢話不多說了,現在就開始。

長度為的數組在標准c和c++中是不允許的,如果使用長度為的數組,編譯時會產生錯誤,提示數組長度不能為。但在GNUc中,這種用法卻是合法的。它的最典型的用法就是位於數組中的最后一項,如上面所示,這樣做主要是為了方便內存緩沖區的管理。如果你將上面的長度為的數組換為指針,那么在分配內存時,需采用兩步:首先,需為結構體分配一塊內存空間;其次再為結構體中的成員變量分配內存空間。這樣兩次分配的內存是不連續的,需要分別對其進行管理。當使用長度為的數組時,則是采用一次分配的原則,一次性將所需的內存全部分配給它。相反,釋放時也是一樣的。

對於長度為的數組,在gcc手冊中,有如下一段代碼片段:

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

struct line *thisline = (struct line *) malloc(sizeof(struct line) + this_length);

thisline->length = this_length;

這段代碼的主要含義是定義了一個結構體,並對其進行初始化,上面結構體的第二個成員變量contents[0]事實上是不占內存空間的,因此整個結構體的長度sizeof(struct line)為4。當采用malloc為其申請內存空間時,如上所示,申請了一段長度為結構體長度加可變長度的內存空間給結構體類型的指針,這時contents就指向申請的可變長度的內存空間。由於是一次申請的,所以這段可變長度的內存空間和前面的結構體長度的內存空間是連續的。對於這段可變長度的內存空間,可以采用數組的方式對其進行訪問。對於整個結構體,當不再使用時,可以使用free函數一次性對其進行釋放,而不必像指針那樣分別釋放。

 

下面舉例進行說明:

#include <stdio.h>
#include <stdlib.h>
#define LENGTH 10

struct test1 {
    int a;
    int *b;
}__attribute((packed));

struct test2 {
    int a;
    int b[0];
}__attribute((packed));

struct test3 {
    int a;
    int b[1];
}__attribute((packed));

int main() {
    struct test1 *var1;
    struct test2 *var2;
    struct test3 *var3;
    int i;

    printf("the length of struct test1:%d\n", sizeof(struct test1));
    printf("the length of struct test2:%d\n", sizeof(struct test2));
    printf("the length of struct test3:%d\n", sizeof(struct test3));

    var1 = (struct test1*) malloc(sizeof(struct test1));
    var1->a = 1;
    var1->b = (int *) malloc(sizeof(int));
    *var1->b = 1;
    printf("\nvar1->a=%d,*(var1->b)=%d\n", var1->a, *var1->b);

    var2 = (struct test2*) malloc(sizeof(struct test2) + sizeof(int) * LENGTH);
    var2->a = 2;
    printf("\nvar2->a=%d\n", var2->a);
    for (i = 0; i < LENGTH; i++) {
        var2->b[i] = i;
        printf("var2->b[i]=%d\t", var2->b[i]);
    }
    printf("\n\n");

    var3 = (struct test3*) malloc(sizeof(struct test3));
    var3->a = 3;
    (var3->b)[0] = 3;
    printf("var3->a=%d,(var3->b)[0]=%d\n", var3->a, (var3->b)[0]);

    free(var1->b);
    free(var1);
    free(var2);
    free(var3);

}

這段程序的運行結果如下圖所示:

從上面的結果可以看出:

1、 長度為的數組並不占有內存空間,而指針方式需要占用內存空間。

2、對於長度為數組,在申請內存空間時,采用一次性分配的原則進行;對於包含指針的結構體,才申請空間時需分別進行,釋放時也需分別釋放。

3、 對於長度為的數組的訪問可采用數組方式進行。

 

原文地址:http://blog.csdn.net/zhaqiwen/article/details/7904515


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM