柔性数组(flexible array)

柔性数组从C99开始支持使用

1.柔性数组的概念

概念:

结构体中,结构体最后一个元素允许是未知大小的数组,这就叫柔性数组的成员

cpp 复制代码
struct S
{
    int n;
    char arr[]; //数组大小未知(柔性数组成员)
};

++柔性数组的特点:++

结构体中柔性数组成员前必须至少有一个其他成员

sizeof返回的这种结构大小不包括柔性数组的内存

cpp 复制代码
struct S
{
    int n;
    char arr[]; 
};
int main()
{  
    printf("%zu\n", sizeof(struct S););   //4
    return 0;
}

由图可知sizeof计算时不会包含柔性数组的大小

2.如何给柔性数组开辟空间呢?

如果结构体中有柔性数组,那么系统应该这么帮结构体开辟空间

怎样使用:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct S
{
    int n;
    char arr[];
}S;

int main()
{
    //sizeof(char)*10 根据需求改变,柔性数组就是可变数组
    S* ptr = (S*)malloc(sizeof(S) + sizeof(char) * 10);
    if (ptr == NULL)
    {
        perror("S::malloc");
        return 1;
    }
    //ptr->n = 4;
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        ptr->arr[i] = 'a';
    }
    for (i = 0; i < 10; i++)
    {
        printf("%c ", ptr->arr[i]);
    }
    // free(ptr);
    // ptr = NULL;
    
    //增容
    S* pc = (S*)realloc(ptr, sizeof(S) + sizeof(char) * 20);
    if(pc == NULL)
    {
       perror("S::realloc");
       return 1;
    }
    else
    {
       ptr = pc;
    }
    free(ptr);
    ptr = NULL; 
    return 0;
}

3.如果我们给柔性数组申请了动态内存会不会改变结构体大小?

不会!!!

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct S
{
    int n;
    char arr[];
}S;

int main()
{
    //sizeof(char)*10 根据需求改变,柔性数组就是可变数组
    S* ptr = (S*)malloc(sizeof(S) + sizeof(char) * 10);
    if (ptr == NULL)
    {
        perror("S::malloc");
        return 1;
    }
    printf("%zu", sizeof(S));
    free(ptr);
    ptr = NULL;
    return 0;
}

运行结果:

形式如图所示:

可以看到申请了空间之后还是4字节

包含柔性数组的结构体用malloc()函数进行内存的动态分配,并且分配的内存大小应该大于结构体的大小,以适应柔性数组的预期大小

4.使用字符型指针代替柔性数组

cpp 复制代码
typedef struct S
{
    int n;
    char* str;
}S;

int main()
{
    printf("%zu", sizeof(S));
    return 0;
}

运行结果:

进行代替

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct S
{
    int n;
    char* str;
}S;

int main()
{
    S* ptr = (S*)malloc(sizeof(S));
    if (ptr == NULL)
    {
        perror("malloc");
        return 1;
    }
    ptr->n = 4;
    ptr->str = (char*)malloc(sizeof(char) * 10);
    if (ptr->str == NULL)
    {
        perror("ptr->str::malloc");
        return 1;
    }
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        ptr->str[i] = 'a';
    }
    for (i = 0; i < 10; i++)
    {
        printf("%c ", ptr->str[i]);
    }
    //增容
    char* pc =(char*)realloc(ptr->str, sizeof(char) * 20);
    if(pc != NULL)
    {
       ptr->str = pc;
    }
    else
    {
       perror("pc::realloc");
       return 1;
    }
    //释放顺序不要弄反,也可以先释放pc
    //如果先释放ptr,ptr->str就没有了
    free(ptr->str);
    ptr->str = NULL;
    free(ptr);
    ptr = NULL;
    return 0;
}

这个形式如图:

5.柔性数组的好处

虽然用char* str也可以实现,但是有弊端

使用柔性数组的好处:

++->1.malloc 只需要使用一次++

++->2.free 只需要使用一次++

++->3.空间是连续的++

与char* str相比

++不容易出错++

++内存碎片少,空间利用率高++

++效率高(访问速度相对快)++

相关推荐
小程故事多_806 小时前
从A2C、TRPO、PPO到GRPO,强化学习策略梯度算法完整演进与大模型落地实战解析
人工智能·算法
2601_956121978 小时前
二分算法(知识点+题目)
c++·算法
AndrewHZ11 小时前
【LLM技术全景】阶段总结:技术原理篇核心知识回顾
人工智能·深度学习·算法·语言模型·大模型·llm·芯片开发
小星星闪亮登场11 小时前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
冻柠檬飞冰走茶12 小时前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法
玖玥拾12 小时前
LeetCode 88 合并两个有序数组
算法·leetcode
数据皮皮侠AI13 小时前
上市公司数字供应链金融指数(2010-2024)
大数据·人工智能·算法
2501_9423895513 小时前
Epoch AI旗下FrontierMath的负责人Elliot Glazer
数据结构·决策树·动态规划·散列表
小程故事多_8013 小时前
用GRPO算法重塑多智能体系统,从原理落地到复杂任务规划实战
人工智能·算法
Hi李耶14 小时前
【LeetCode】541.反转字符串 II
算法·leetcode·职场和发展