struct test1
{
int a;
int *b;
};
struct test2
{
int a;
int b[0];
};
struct test3
{
int a;
int b[1];
};
长度为0的数组在标准c和c++中是不允许的,如果使用长度为0的数组,编译时会产生错误,提示数组长度不能为0。但在GNU C中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面test2所示,这样做主要是为了方便内存缓冲区的管理。对上面3种定义方法进行比较:
1.对于test1,数组用指针表示,那么在分配内存时,需采用两步:
首先,需为结构体分配一块内存空间;
其次再为结构体中的成员变量分配内存空间。
这样两次分配的内存是不连续的,需要分别对其进行管理。释放时也是一样的,需要单独释放指针,再释放结构体。
2.对于test2,数组用零数组表示,在分配内存空间时,能够一次性分配内存空间(见下例),释放时也是一样,只需要一次一起释放。
3.对于test3,数组用用标准数组方式,这样在分配和释放内存空间时也能一次性完成。
通过以上比较或许看不出零数组有什么特别,可以想一下:如果数组在后续中不一定能用到,test3不管怎样都分配了空间,test1用到时分配和释放都要多一步且至少已经占用了4byte的空间(int的空间),而test2形式就灵活得多,这样一比,或许就能看出零数组的一点好处了。
或许有的人会说用数组就不用分别分配内存空间了,但可以想一想,
完整示例(测试环境为VS2010):
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define LENGTH 10
struct test1
{
int a;
int *b;
};
struct test2
{
int a;
int b[0];
};
struct test3
{
int a;
int b[1];
};
int main(int argc,char **argv)
{
struct test1 *var1;
struct test2 *var2;
struct test3 *var3;
int i;
printf("the length of struct test1:%d ",sizeof(struct test1));
printf("the length of struct test2:%d ",sizeof(struct test2));
printf("the length of struct test3:%d ",sizeof(struct test3));
var1=(struct test1*)malloc(sizeof(struct test1));
var1->a=1;
var1->b=(int *)malloc(sizeof(int));
*var1->b=1;
printf(" var1->a=%d,*(var1->b)=%d ",var1->a,*var1->b);
var2=(struct test2*)malloc(sizeof(struct test2)+sizeof(int)*LENGTH); //l零数组现在包含10个元素。
var2->a=2;
printf(" var2->a=%d ",var2->a);
for(i=0;i<LENGTH;i++)
{
var2->b[i]=i;
printf("var2->b[i]=%d ",var2->b[i]);
}
printf(" ");
var3=(struct test3*)malloc(sizeof(struct test3));
var3->a=3;
(var3->b)[0]=3;
printf("var3->a=%d,(var3->b)[0]=%d ",var3->a,(var3->b)[0]);
free(var1->b); //先free指针
free(var1); //再free结构体
free(var2);
free(var3);
system("pause");
return 0;
}
本文灵感来自“拾月彷徨”的这篇博客:http://my.oschina.net/u/176416/blog/33054