零长度数组解析

来源:互联网 发布:淘宝实战培训 编辑:程序博客网 时间:2024/06/05 11:44

接触了linux编程之后,经常会遇到一个很诡异的零长度数组,今天决定深挖一下。

Struct command {

    Int domain;

    Int length;

    Char bytes[0];//也可以写成char bytes[];

}

在某一结构末尾如定义类似 char bytes[0] 的零长度数组,表示该结构不定长,可通过数组的方式进行扩展。结构中必包含一个长度信息。结构本身类似于一个信息头。同时,此结构只能通过堆方式分配内存。零长度数组不占用实际的空间,但能通过数组名访问到其指向的地址。

零长度数组不是所有的c标准都支持,gnu c支持,ansic不支持,c++不支持。也即标准c和c++中是不允许的,怪不得windows环境下编程是没见过这玩意。

可以把结构体中定义了零长度数组的地方视为结构体的结尾,在它之后最好不要再定义任何字段。因为零长度数组用来动态的添加数据,一旦添加数据后,零长度数组字段之后定义的字段如果之前赋了值,那么这个值就会被改掉。

这样设计主要是为了方便内存缓冲区的管理。如果你将上面的长度为的数组换为指针,那么在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。

由于是一次申请的,所以这段可变长度的内存空间和前面的结构体长度的内存空间是连续的。对于这段可变长度的内存空间,可以采用数组的方式对其进行访问。对于整个结构体,当不再使用时,可以使用free函数一次性对其进行释放,而不必像指针那样分别释放。

优点:

长度为零的数组并不占有内存空间,而指针方式需要占用内存空间。

对于长度为零的数组,在申请内存空间时,采用一次性分配的原则,释放时也是一次性释放;对于包含指针的结构体,在申请空间时需分别进行,释放时也需分别释放。

#include<stdio.h>Struct command {    Int domain;    Int length;    Char bytes[0];//也可以写成char bytes[];} int main(){    structcommand * p_cmd =(structcommand *)malloc(sizeof(struct device)+sizeof(char)*128);    //多分配了128个字节,这才是最重要的。分配的是连续的地址。     p_cmd->bytes[0]= ‘t’;    p_cmd->bytes[16]= ‘s’;    printf("sizeof(struct command) = %d\n",sizeof(struct command));   return 0;}


 

0 0
原创粉丝点击