C语言长度为0的数组
前面在看Xen的源碼時(shí),遇到了一段代碼,如下所示:
注意上面最后一行的代碼,這里定義了一個長度為的數(shù)組,這種用法可以嗎?為什么可以使用長度為0?的數(shù)組?長度為的數(shù)組到底怎么使用?……這篇文章主要針對該問題進(jìn)行簡單的講解。廢話不多說了,現(xiàn)在就開始。
長度為的數(shù)組在標(biāo)準(zhǔn)c和c++中是不允許的,如果使用長度為的數(shù)組,編譯時(shí)會產(chǎn)生錯誤,提示數(shù)組長度不能為。但在GNUc中,這種用法卻是合法的。它的最典型的用法就是位于數(shù)組中的最后一項(xiàng),如上面所示,這樣做主要是為了方便內(nèi)存緩沖區(qū)的管理。如果你將上面的長度為的數(shù)組換為指針,那么在分配內(nèi)存時(shí),需采用兩步:首先,需為結(jié)構(gòu)體分配一塊內(nèi)存空間;其次再為結(jié)構(gòu)體中的成員變量分配內(nèi)存空間。這樣兩次分配的內(nèi)存是不連續(xù)的,需要分別對其進(jìn)行管理。當(dāng)使用長度為的數(shù)組時(shí),則是采用一次分配的原則,一次性將所需的內(nèi)存全部分配給它。相反,釋放時(shí)也是一樣的。
對于長度為的數(shù)組,在gcc手冊中,有如下一段代碼片段:
struct?line?{
int?length;
char?contents[0];
};
struct?line?*thisline?=?(struct?line?*)malloc?(sizeof?(struct?line)?+?this_length);
thisline->length?=?this_length;
這段代碼的主要含義是定義了一個結(jié)構(gòu)體,并對其進(jìn)行初始化,上面結(jié)構(gòu)體的第二個成員變量contents[0]事實(shí)上是不占內(nèi)存空間的,因此整個結(jié)構(gòu)體的長度sizeof(struct?line)為4。當(dāng)采用malloc為其申請內(nèi)存空間時(shí),如上所示,申請了一段長度為結(jié)構(gòu)體長度加可變長度的內(nèi)存空間給結(jié)構(gòu)體類型的指針,這時(shí)contents就指向申請的可變長度的內(nèi)存空間。由于是一次申請的,所以這段可變長度的內(nèi)存空間和前面的結(jié)構(gòu)體長度的內(nèi)存空間是連續(xù)的。對于這段可變長度的內(nèi)存空間,可以采用數(shù)組的方式對其進(jìn)行訪問。對于整個結(jié)構(gòu)體,當(dāng)不再使用時(shí),可以使用free函數(shù)一次性對其進(jìn)行釋放,而不必像指針那樣分別釋放。
下面舉例進(jìn)行說明:
#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);
}
這段程序的運(yùn)行結(jié)果如下圖所示:
從上面的結(jié)果可以看出:
l?長度為的數(shù)組并不占有內(nèi)存空間,而指針方式需要占用內(nèi)存空間。
l?對于長度為數(shù)組,在申請內(nèi)存空間時(shí),采用一次性分配的原則進(jìn)行;對于包含指針的結(jié)構(gòu)體,才申請空間時(shí)需分別進(jìn)行,釋放時(shí)也需分別釋放。
l?對于長度為的數(shù)組的訪問可采用數(shù)組方式進(jìn)行。
總結(jié)
以上是生活随笔為你收集整理的C语言长度为0的数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL 命令【精华帖】
- 下一篇: vimdiff