首页 > 技术文章 > 柔性数组

ggzhangxiaochao 2022-02-08 17:08 原文

1、零长度数组概念

0长度数组, 也叫柔性数组。

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

struct Packet
{
    int state;
    int len;
   //cData就是柔性数组 
    char cData[0]; //这里的0长结构体就为变长结构体提供了非常好的支持
};

用法 : 在一个结构体的最后, 申明一个长度为0的数组, 就可以使得这个结构体是可变长的.

对于编译器来说, 此时长度为0的数组并不占用空间, 因为数组名本身不占空间, 它只是一个偏移量,

数组名这个符号本身代表了一个不可修改的地址常量。

注意 :数组名永远都不会是指针, 但对于这个数组的大小, 我们可以进行动态分配。
注意 :如果结构体是通过calloc、malloc或 者new等动态分配方式生成,在不需要时,要释放相应的空间。
优点 :比起在结构体中声明一个指针变量、再进行动态分 配的办法,这种方法效率要高。因为在访问数组内容时,不需要间接访问,避免了两次访存。
缺点 :在结构体中,数组为0的数组必须在最后声明,使 用上有一定限制。

2、零长度数组比较

// zero_length_array.c
#include <stdio.h>
#include <stdlib.h>


#define MAX_LENGTH      1024
#define CURR_LENGTH      512

//  0长度数组
struct zero_buffer
{
    int     len;
    char    data[0];
}__attribute((packed));


//  定长数组
struct max_buffer
{
    int     len;
    char    data[MAX_LENGTH];
}__attribute((packed));


//  指针数组
struct point_buffer
{
    int     len;
    char    *data;
}__attribute((packed));

int main(void)
{
    struct zero_buffer  *zbuffer = NULL;
    struct max_buffer   *mbuffer = NULL;
    struct point_buffer *pbuffer = NULL;


    // =====================
    // 0长度数组  占用-开辟-销毁
    // =====================
    ///  占用
    printf("the length of struct test1:%d\n",sizeof(struct zero_buffer));
    ///  开辟
    if ((zbuffer = (struct zero_buffer *)malloc(sizeof(struct zero_buffer) + sizeof(char) * CURR_LENGTH)) != NULL)
    {
        zbuffer->len = CURR_LENGTH;
        memcpy(zbuffer->data, "Hello World", CURR_LENGTH);


        printf("%d, %s\n", zbuffer->len, zbuffer->data);
    }
    ///  销毁
    free(zbuffer);
    zbuffer = NULL;


    // =====================
    // 定长数组  占用-开辟-销毁
    // =====================
    ///  占用
    printf("the length of struct test2:%d\n",sizeof(struct max_buffer));
    ///  开辟
    if ((mbuffer = (struct max_buffer *)malloc(sizeof(struct max_buffer))) != NULL)
    {
        mbuffer->len = CURR_LENGTH;
        memcpy(mbuffer->data, "Hello World", CURR_LENGTH);


        printf("%d, %s\n", mbuffer->len, mbuffer->data);
    }
    /// 销毁
    free(mbuffer);
    mbuffer = NULL;

    // =====================
    // 指针数组  占用-开辟-销毁
    // =====================
    ///  占用
    printf("the length of struct test3:%d\n",sizeof(struct point_buffer));
    ///  开辟
    if ((pbuffer = (struct point_buffer *)malloc(sizeof(struct point_buffer))) != NULL)
    {
        pbuffer->len = CURR_LENGTH;
        if ((pbuffer->data = (char *)malloc(sizeof(char) * CURR_LENGTH)) != NULL)
        {
            memcpy(pbuffer->data, "Hello World", CURR_LENGTH);


            printf("%d, %s\n", pbuffer->len, pbuffer->data);
        }
    }
    /// 销毁
    free(pbuffer->data);
    free(pbuffer);
    pbuffer = NULL;


    return EXIT_SUCCESS;
}
  • 柔性数组并不占有内存空间, 而指针方式需要占用内存空间。

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

  • 对于柔性数组的访问可采用数组方式进行。

 

参考引用链接:

https://zhuanlan.zhihu.com/p/94855692

https://www.cnblogs.com/veis/p/7073076.html

https://blog.csdn.net/gatieme/article/details/64131322

推荐阅读