当前位置: 首页 > news >正文

【C语言进阶】柔性数组

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

目录

1.  什么是柔性数组

2.柔性数组的特点

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


1.  什么是柔性数组

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

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个字节,当然开辟完毕之后需要判断是否为空指针。

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;
}

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

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

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次数过多,那么内存碎片的数量就会越多,内存利用率会降低;换言之连续的内存存储有利于提高访问速度,减少内存碎片,提高内存利用率。

http://www.dtcms.com/a/295988.html

相关文章:

  • 电商项目_秒杀_架构升级
  • 第十八天(Linux基本命令)
  • ollama无法拉取模型导致报错
  • Spring AI 系列之二十三 - AudioModels
  • 20250724-day21
  • 自己开发VUE之web网页打包技术毕业论文——仙盟创梦IDE
  • 通过为前端项目接入GeoGebra,初步研究AI时代数学教案的生成方案
  • 深度解析:在Odoo 18中基于原生Owl框架为PWA定制功能丰富的底部导航栏
  • 后端分页接口实现
  • 在一个网页浏览器的控制台测试后端java是否支持SSE服务
  • 小旺AI截图v1.2.3版本上线,自定义快捷键全覆盖
  • 从零用java实现 小红书 springboot vue uniapp(15) 集成minio存储 支持本地和minio切换
  • Could not open JDBC Connection for transaction 问题
  • 基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
  • 卫星物联网:使用兼容 Arduino 的全新 Iridium Certus 9704 开发套件深入探索
  • 人工智能与云计算双轮驱动:元宇宙如何重构全球产业生态
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-评论用户名词云图实现
  • 亚纳米级检测!潜望式棱镜的“检测密码”,决定手机远景清晰度
  • 4G手机控车模块的核心功能与应用价值
  • 4种灵活的方法从POCO手机中删除联系人
  • 天邑TY1613_S905L3SB_安卓9-高安非-高安版-通刷-TTL线刷固件包
  • 考研初试专业分146!上岸新疆大学!信号与系统考研经验,通信考研小马哥。
  • 图机器学习(20)——欺诈交易检测算法
  • python基础:操作列表
  • 2024年ASOC SCI2区TOP,基于强化学习教与学优化算法RLPS-TLBO+风电场布局优化,深度解析+性能实测
  • 一种宏模板实现方法
  • (实用攻略)Linux操作系统(一)
  • 强制缓存与协商缓存
  • CentOS7 安装 rust 1.82.0
  • C语言转义字符‘\\‘‘ 解析与常见误区