c语言局部数组长度,C语言0长度数组(柔性数组)

本文介绍了C语言中0长度数组的概念,它常用于实现变长数组,尤其是在TLV数据结构中。虽然标准C和C++不推荐使用,但GNU C允许。通过示例展示了如何分配和使用这种结构体,以及释放内存后应注意的问题。同时,区分了0长度数组与严格意义上的弹性数组的区别,并强调了它们在内存管理和使用上的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0长度数组,又称为柔性数组(flexible array)。通经常使用来实现变长数组。常见于TLV(type-length-value)的数据结构中。在标准 C 和 C++ 中,不同意用 0 长度数组,但在

GNU C 中,却能够定义 0 长度数组(在C99之前写成长度为0,C99中能够直接不写索引)。一般会拿手冊中给的样例来说明

struct line {

int length;

char contents[0]; // char contents[]; //C99

}

从打印出来的结构体尺寸 sizeof (struct line) = 4 (和编译器有关,看内存对齐规则),能够看到contents[0]不占有空间(不同于字符指针类型),它存在的优点是在结构体的后面同意我们自己申请一定大小的存储空间,而不是每次都使用 MAX_SIZE 大小的结构体。通常的用法例如以下:

int this_length = 60;

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

thisline->length = this_length;

通过測试代码能够发现:为0长度数组分配的空间紧跟着该该结构体最后一个字段之后,并且释放结构体指针后。我们自己分配的空间也会释放(不同于有些网上的说法)。所以须要注意的是我们释放的是由某个指针指向的内存空间,而非指针,指针变量是在程序结束后回收的,所以在我们释放一段内存之后要将其置为NULL,否则还是能够訪问的,只是訪问到的都是垃圾数据。

測试代码:FlexibleArray.c

#include

#include

struct line {

int length;

char test;

char contents[0];//or char contents[];

};

int main(){

int i;

int this_length = 60;

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

thisline->length = this_length;

printf ("thisline addr is %p

", thisline);

printf ("thisline->length field value is %d

",thisline->length);

printf ("thisline->length field addr is %p

", &thisline->length);

printf ("thisline->test field addr is %p

", &thisline->test);

printf ("thisline->contents field addr is %p

", &thisline->contents);

printf ("thisline->contents[0] addr is %p

", &thisline->contents[0]);

printf ("thisline->contents[0] addr is %p

", &thisline->contents[1]);

for(i=0; i<3; i++){

thisline->contents[i] = 'a' + i;

}

char *p = thisline->contents;

printf("%c

", p[2]);

free(thisline);

//After free , when we access the space ,we got garbage data;

printf("%d

", thisline->length);

printf("%c

", p[2]);

return 0;

}

执行效果:

22c718f1e9590dbebd4e762a3f69ba54.png

update:2015-4-8

FlexibleArray2.c

#include

#include

#include

struct line {

int length;

char test;

char contents[0];

};

int main(){

int i;

char s[20] = "Hello World.";

int that_length = 60;

struct line thisline = {5, 'A', {'a', 'b', 'c'}};

struct line *thatline = malloc(sizeof(struct line) + that_length);

thatline->length = that_length;

for(i=0; i<3; i++){

thatline->contents[i] = 'A' + i;

}

char *p = thatline->contents;

printf("%c

", p[2]);

free(thatline->contents);

thatline->contents = thisline.contents;

// error: incompatible types when assigning to type ‘char[]’ from type ‘char *’

p = thatline->contents;

printf("%c

", p[2]);

return 0;

}

Center

能够看到根本无法改动一个实例中contents的指向,所以占用的是完整的内存区间。不能指向单独的地址空间。

FlexibleArray3.c

#include

#include

#include

struct line {

int length;

char test;

char contents[];

};

int main(){

struct line thisline = {5, 'A', {'a', 'b', 'c'}};

return 0;

}

23e7355a21d13d43891b1ae14f172b81.png

能够看到严格的弹性数组和长度0的数组还是有差别的,这里就不能使用静态初始化。仅仅能像FlexibleArray1.c中那样操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值