Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

GNU C的零长数组和用法

$
0
0
作者:Sam (甄峰)  sam_code@hotmail.com

在Linux Kernel或一些GNU项目中,可以看到长度设定为0的数组。之前没有深究,这次研究一下。
以下内容大量摘抄网上信息。

标准C和C++不支持0长度数组。如果定义0长数组。编译阶段就会报错。但GNU C支持零长数组,条件是作为结构体的最后一项。

但这一项因为长度为0,所以不占空间。

举例如下:

#include                 //stdio.h
#include          //sys/types.h
#include               //stdint.h
#include     // stdlib.h

typedef struct {
uint8_t subevent;
uint8_t data[0];
} __attribute__ ((packed)) test_event;

int main(int argc, char** argv)
{
int ext_size = 12;
char Letter = 'A';

printf("\nSize is: %d\n", sizeof(test_event));

test_event* event = (test_event*) malloc(sizeof(test_event)+ 9);
for(int i = 0; i < ext_size; i++)
{
event->data[i] = Letter++;
}

printf("\n");
for(int i = 0; i < ext_size; i++)
{
printf("%c\t", event->data[i]);
}

    return 0;
}


可以看到结果是:
Size is: 1
A       B       C       D       E       F       G       H       I       J       K       L 

这个用法主要用于变长Buffer。 结构体大小为1, data[0]不占任何空间。 如果采用另一个方法,比如把data设置为指针,也可以实现此功能。但首先这个执针本身需要占用4bytes.  而且还需要申请新内存再要指针指向它。
这样的话,内存不连续,且要分别管理。
而是用零长度数组。申请时,内存长度为机构体长度+数组长度。内存空间连续。释放时也只需释放一次。


用途 :长度为0的数组的主要用途是为了满足需要变长度 的结构体。

用法 :在一个结构体的最后 ,申明一个长度为0的数组,就可以使得这个结构体是可变长的。对于 编译器来说,此时长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名永远都不会是指针! ),但对于这个数组的大小,我们可以进行动态分配。例如:

typedef struct{
       int len;
       char data[0];
}test_t;

int my_length = 10;

test_t *p_test = (test_t *)malloc(sizeof(test_t) + my_length);
p_test->len = my_length;

......

free(p_test);    

之后对于结构体中的数组可以像一般的数组一样进行访问。




 

Viewing all articles
Browse latest Browse all 158

Trending Articles