C语言0长度数组(柔性数组)

0长度数组,又称为柔性数组(flexible array),通常用来实现变长数组,常见于TLV(type-length-value)的数据结构中。在标准 C 和 C++ 中,不允许用 0 长度数组,但在
GNU C 中,却可以定义 0 长度数组。通常会拿手册中给的例子来说明

struct line {

int length;

char contents[0];

}

从打印出来的结构体尺寸 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 <stdio.h>
#include <stdlib.h>

struct line {
         int length;
         char test;
         char contents[0];
    };

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\n", thisline);
    printf ("thisline->length field value is %d\n",thisline->length);
    printf ("thisline->length field addr is %p\n", &thisline->length);
    printf ("thisline->test field addr is %p\n", &thisline->test);
    printf ("thisline->contents field addr is %p\n", &thisline->contents);
    printf ("thisline->contents[0] addr is %p\n", &thisline->contents[0]);
    printf ("thisline->contents[0] addr is %p\n", &thisline->contents[1]);

    for(i=0; i<3; i++){
        thisline->contents[i] = 'a' + i;
    }

    char *p = thisline->contents;
    printf("%c\n", p[2]);

    free(thisline);
    //After free , when we access the space ,we got garbage data;
    printf("%d\n", thisline->length);
    printf("%c\n", p[2]);

    return 0;
}

运行效果:

C语言0长度数组(柔性数组)

时间: 2024-10-20 09:17:12

C语言0长度数组(柔性数组)的相关文章

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占用int长度空间,空数组不占任何空间.“这个数组不占用任何内存”,意味着这样的结构节省空间:“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用. 这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(struc

C语言柔性数组

柔性数组:数组大小待定的数组.C语言中结构体最后一个元素可以是大小未知的数组.C语言可以由结构体产生柔性数组 柔性数组的结构如何只能堆上生成 柔性数组是C99的扩展,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间). #include <stdio.h> #include <malloc.h> typedef struct _soft_array { int len; int array[]; }SoftArray; int main() { int

柔性数组

柔性数组 * 柔性数组即数组大小待定的数组 * C语言中结构体的最后一个元素可以是大小未知的数组 * C语言中可以由结构体产生柔性数组 #include <stdio.h> #include <malloc.h> typedef struct _soft_array { int len; int array[]; }SoftArray; int main() { int i = 0; SoftArray* sa = (SoftArray*)malloc(sizeof(SoftArr

(转)C语言中长度为0的数组

前面在看Xen的源码时,遇到了一段代码,如下所示: 注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0 的数组?长度为的数组到底怎么使用?……这篇文章主要针对该问题进行简单的讲解.废话不多说了,现在就开始. 长度为的数组在标准c和c++中是不允许的,如果使用长度为的数组,编译时会产生错误,提示数组长度不能为.但在GNUc中,这种用法却是合法的.它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理.如果你将上面的长度为的

柔性数组(结构体最后一个域为0/1数组)

结构体最后的长度为0或1数组的作用(转载) 2012-05-07 17:07:09 其实很 早在看LINUX下就看到这个东西,后来在MFC内存池里同样也看到了类似的东西,还依照MFC写过一个类似的小内存池,(MFC用的是return this + 1)后来在李先静的<系统程序员成长计划>里看到了类似的定义,于是心里想着总结一下,结果发现网上已经有牛人总结的很好了,于是乎就转了过来,谢谢你们 的分享,这是我前进的动力!同时,需要引起注意的:ISO/IEC 9899-1999里面,这么写是非法的,

C语言柔性数组讲解

#include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { int len = 10; printf("The struct's size is %d\n",sizeof(SoftArray)); } 我们可以看出,_SoftArray结构体的大小是4,显然,在32位操作系统下一个int型变量大小刚好为4,也就说结构体中的数组没有占用内存.为什么会没有

C语言柔性数组和动态数组

[前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { int len = 10; printf("The struct's size is %d\n",sizeof(SoftArray));

c语言关键字-struct,union,enum及柔性数组

一.struct关键字与柔性数组 c语言中的struct可以看做变量的集合,struct中的每个数据成员都有独立的存储空间 柔性数组:柔性数组在C99中也称之为伸缩型数组,是C99的扩展,简言之就是struct结构里的标识占位符(不占用struct的空间),柔性数组的结构只能在堆上生成. 声明柔性数组的规则 柔性数组成员必须为结构(struct)中的最后一个成员 结构中至少有一个其他成员 柔性数组就像普通数组一样被声明,除了它的方括号内为空 1 struct softarry 2 { 3 int

程序猿之---C语言细节29(#define宏大小、空结构体大小、柔性数组不知道你见过没)

主要内容:#define宏大小.空结构体大小.柔性数组 一.#define宏大小 见例子 二.空结构体大小 根编译器有关 三.柔性数组 不常用,可看看 #include <stdio.h> #define N 4 #define STR "abcd" int main() { struct student { }stu; printf("N = %d\n", sizeof(N)); printf("num 5 memery = %d\n&quo