【C语言进阶】柔性数组

学习了动态内存管理和结构体之后,我们可以开始学习柔性数组~

目录

[1. 什么是柔性数组](#1. 什么是柔性数组)

2.柔性数组的特点

[2.1 柔性数组两种开辟空间的方式](#2.1 柔性数组两种开辟空间的方式)


1. 什么是柔性数组

在结构体中的最后一个成员是一个没有指定大小的数组,那么这个数组叫做柔性数组。

cpp 复制代码
typedef struct st_type
{
    int i;
    int a[0]; // 柔性数组成员
};

typedef struct st_type
{
    int i;
    int a[]; // 编译不通过可以将0去掉
};

2.柔性数组的特点

柔性数组具有以下特点:

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

②sizeof返回的结构体大小不包含柔性数组的内存。

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

最后一点是什么意思呢,我们可以看下面的图片,我们使用malloc创建结构体变量,除了结构体本身的4个字节,我们还需要给柔性数组分配40个字节的变量,这里将返回的地址给了ps,内存布局如下图所示:

2.1 柔性数组两种开辟空间的方式

由于arr数组是由malloc分配的堆空间,所以这里可以使用relloc进行扩容。,如下图所示,我们又增加了80个字节,当然开辟完毕之后需要判断是否为空指针。

cpp 复制代码
struct S 
{
    int n;
    int* arr;
};



int main()
{
    
    struct S* ps = (struct S*)malloc(sizeof(struct S) + 40);
    ps -> n = 100;
    for(int i = 0;i < 10; i++)
    {
        ps->arr[i] = i;
    }
    struct S* ptr = (struct S*)realloc(ps,sizeof(struct S) + 80);
    if(ptr != NULL)
    {
        ps = ptr;
    }

    return 0;
}

当使用完毕之后,我们只需要进行手动释放即可。

除了想上面那样直接一次开辟空间,我们还可以多次开辟空间达到效果;

cpp 复制代码
struct S 
{
    int n;
    int* arr;
};



int main()
{
    
    struct S* ps = (struct S*)malloc(sizeof(struct S));
    if(ps == NULL)
    {
        return 1;
    }
    ps -> n= 100;
    ps ->arr =  (int*)malloc(40);
    if(ps -> arr == NULL)
    {
        return 1;
    }
    for(int i  = 0;i < 10;i++)
    {
        ps->arr[i] = i;
    } 

    // 释放
    free(ps->arr); 
    free(ps);
    ps = NULL;  
}

需要注意的是,arr和结构体是分别开辟空间的,结构体包含arr,所以释放的时候先释放arr,再释放结构体;如果先释放结构体,那么arr就找不到了。

那么这两种开辟空间的方式哪一种更好呢?第一种方案需要开辟、释放一次空间,第二种方案需要开辟、释放空间两次,后者更容易发生内存泄露,当malloc次数过多,那么内存碎片的数量就会越多,内存利用率会降低;换言之连续的内存存储有利于提高访问速度,减少内存碎片,提高内存利用率。

相关推荐
白帽攻防录5 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛5 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
和侧5 小时前
离子注入后为什么必须配套退火工艺?
笔记·学习
2603_965148116 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
生态学者6 小时前
Global Change Biology | 森林越“步调一致”,反而越怕干旱?树木生长与叶片活动的同步之谜
大数据·人工智能·算法·r语言·微信公众平台
所以遗憾是什么呢?6 小时前
【题解】Educational Codeforces Round 195 (Rated for Div. 2) ABCDE
c++·动态规划·acm·icpc·ccpc·xcpc·codeforecs
凛铄linshuo6 小时前
自动化测试:pytest第一个实例学习
学习·pytest
xixiaoyunya6 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
lsswear6 小时前
Agent 框架新手入门与实战部署指南
大数据·人工智能·算法
学逆向的7 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全