• 柔性数组


    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

  • 相关阅读:
    Java实现蓝桥杯模拟组织晚会
    Java实现蓝桥杯模拟组织晚会
    ffmpeg+rtsp+dss
    开发ffmpeg/live555常见问题错误及解决方法
    SxsTrace工具使用方法
    移植strace调试工具到arm平台
    Linux on Power 上的调试工具和技术
    使用 Strace 和 GDB 调试工具的乐趣
    自助Linux之问题诊断工具strace
    通用Makefile
  • 原文地址:https://www.cnblogs.com/ggzhangxiaochao/p/15871991.html
Copyright © 2020-2023  润新知