你真的了解C语言中的【柔性数组】吗~

柔性数组

  • 1. 什么是柔性数组
  • 2. 柔性数组的特点
  • 3. 柔性数组的使用
  • 4. 柔性数组的优势

1. 什么是柔性数组

也许你从来没有听说过柔性数组这个概念,但是它确实是存在的。
C99中,结构体中的最后⼀个元素允许是未知大小的数组,这就叫做柔性数组成员

例如:

struct S
{int i;int arr[];//柔性数组成员
};

2. 柔性数组的特点

  • 结构体中的柔性数组成员前面必须至少有一个其他成员
  • sizeof返回的这种结构体大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构体用malloc函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

例如:

#include <stdio.h>struct S
{int i;int arr[];//柔性数组成员
};int main()
{int sz = sizeof(struct S);printf("%d\n", sz);return 0;
}

输出结果:

在这里插入图片描述

3. 柔性数组的使用

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>struct S
{int i;int arr[];//柔性数组成员
};int main()
{//struct S s;//只申请了4字节空间,柔性数组没有申请空间struct S* ps=(struct S*)malloc(sizeof(struct S) + 40);//40字节是给柔性数组开辟的if (ps == NULL){printf("%s\n", strerror(errno));return 1;}//使用ps->i = 100;int i = 0;for (i = 0; i < 10; i++){ps->arr[i] = i;}for (i = 0; i < 10; i++){printf("%d ", ps->arr[i]);}//调整空间,柔性数组柔性的体现struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 80);if (ptr != NULL){ps = ptr;ptr = NULL;}//……//释放free(ps);ps = NULL;return 0;
}

当前代码的内存布局如图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/391dc6b00d254d6d8af2e3542019c372.png

思考:有人会想到那为什么那为什么不直接让结构体成员为int* ,然后动态开辟一块空间给int* 指向呢?

代码实现如下:

#include <stdio.h>
#include <stdlib.h>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;}//使用int i = 0;for (i = 0; i < 10; i++){ps->arr[i] = i;}for (i = 0; i < 10; i++){printf("%d ", ps->arr[i]);}//扩容int* ptr = (int*)realloc(ps->arr, 80);if (ptr != NULL){ps->arr = ptr;}//释放free(ps->arr);free(ps);ps = NULL;return 0;
}

内存布局如图所示:

在这里插入图片描述

在结构体中这两种方式都能实现“柔性”的效果(空间可调整),哪一种方式更好呢?我们进行对比:

在方式1中使用柔性数组时,n和arr的空间只要使用一次malloc就可以全部开辟,最后一次free就可以释放。

而方式2中struct需要一次malloc开辟,arr又需要malloc开辟,最后也要2次free才可以释放

我们知道使用malloc的次数越多,如果忘记了free,则就越容易造成内存泄漏,其次就是如果在内存中频繁的进行malloc,则形成的内存碎片也越多,这样会使内存的利用率更低。

4. 柔性数组的优势

  1. 方便内存释放
    如果我们的代码是在⼀个给别人用的函数中,你在里面做了⼆次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给用户⼀个结构体指针,用户做⼀次free就可以把所有的内存也给释放掉。

  2. 这样有利于访问速度
    连续的内存有益于提高访问速度,也有益于减少内存碎片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 学习(五)之 高级映射

目录 1 association 和 collection 介绍 2 案例分析 3 一对一关联和一对多关联 4 参考文档 1 association 和 collection 介绍 在之前的 SQL 映射文件中提及了 resultMap 元素的 association 和 collection 标签&#xff0c;这两个标签是用来关联查询的&#xff0c;它们的属…

算法--时空复杂度分析以及各个数据量对应的可使用的算法(C++;1s内)

这里写目录标题 由数据范围反推算法时间复杂度以及算法内容分析时间复杂度看循环实例1实例2 固定时间复杂度快排和归并排序二分高精度算法双指针算法单链表插入删除操作栈和队列的操作单调栈和单调队列KMPTire并查集堆哈希表BFS、DFS图的深度优先、宽度优先遍历dijkstra算法朴素…

题目 1037: [编程入门]宏定义的练习

问题描述&#xff1a; 输入两个整数&#xff0c;求他们相除的余数。用带参的宏来实现&#xff0c;编程序。 样例输入&#xff1a; 3 2 样例输出&#xff1a; 1 代码分析&#xff1a; 这段代码实现了输入两个整数&#xff0c;然后使用带参数的宏计算它们相除的余数&…

「MySQL」深入理解MySQL中常用的SQL函数

「MySQL」深入理解MySQL中常用的SQL函数 窗口函数参考文章1. COALESCE 函数2. USING 函数3. LEAD 函数4. interval 函数5. INSTR 函数6. substring_index 函数7. LENGTH 函数和 CHAR_LENGTH 函数 窗口函数参考文章 SQL窗口函数 1. COALESCE 函数 COALESCE 函数的作用是从一…

瑞_Redis_Redis的Java客户端

文章目录 1 Redis的Java客户端1.1 Jedis快速入门1.1.1 入门案例1.1.1.1 项目构建1.1.1.2 引入依赖1.1.1.3 建立连接1.1.1.4 释放资源1.1.1.5 测试1.1.1.6 完整测试类代码 1.1.2 Jedis连接池1.1.2.1 连接池工具类1.1.2.2 改造原始代码 &#x1f64a; 前言&#xff1a;本文章为瑞…

基于单片机的声光控制节能灯设计

摘 要:在当今社会,节约用电是低碳生活的基本行为之一,但是一些公众场所电力浪费现象依然存在,特别是长明灯、常亮屏等屡见不鲜,造成了严重的电力浪费。针对这种电力浪费现象,该文基于STC89C52单片机设计了一种声光控制节能灯,利用光敏电阻、光信息及语音信号控制电路收集…

常用sql语句及其优化

文章目录 介绍常用sql语句1. 数据查询1.1 SELECT 语句1.2 DISTINCT 关键字1.3 WHERE 子句1.4 ORDER BY 子句1.5 LIMIT 关键字 2. 数据更新2.1 INSERT INTO 语句2.2 UPDATE 语句2.3 DELETE FROM 语句 3. 数据管理3.1 CREATE TABLE 语句3.2 ALTER TABLE 语句3.3 DROP TABLE 语句 …

蓝桥辅导之管道

蓝桥辅导之管道 核心思想&#xff1a;二分 二分时间 若t时刻成立 则之后也一定成立将mid时刻时每个阀门的水的流动区间加入对组 合并区间 最终判断是否覆盖全管道l1 && r m; #include <iostream>#include <cstring>#include <algorithm>#define…

批量自动加好友神器!微信快速扩友秘籍!

对于一些个人或者企业来说&#xff0c;传统的人工添加好友方式往往会出现效率低下&#xff0c;费时费力的问题。那么&#xff0c;有没有一种快速、便捷、安全的方式来解决这个问题呢&#xff1f;答案当然是肯定的&#xff0c;那就是通过使用微信管理系统来解决这一问题。 在微…

基于java+springboot景区行李寄存管理系统设计和实现

基于javaspringboot景区行李寄存管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…

5GC SBA架构

协议标准&#xff1a;Directory Listing /ftp/Specs/archive/23_series/23.501/ (3gpp.org) NF描述说明NSSFNetwork Slice Selection Function网络切片选择&#xff0c;根据UE的切片选择辅助信息、签约信息等确定UE允许接入的网络切片实例。NEF Network Exposure Function网络开…

疾控中心的污水采样瓶用的是什么材质

疾控中心的污水采样瓶采用的材质是聚乙烯或聚丙烯塑料。这种材质的污水采样瓶具有耐腐蚀、耐高压、无毒无味、重量轻、易于携带等优点。此外&#xff0c;这种材质的污水采样瓶还可以在高温下消毒&#xff0c;不会变形或破裂。 疾控中心的污水采样瓶通常有不同的容积和形状&…

Harbor高可用(haproxy和keepalived)

Harbor高可用&#xff08;haproxy和keepalived&#xff09; 文章目录 Harbor高可用&#xff08;haproxy和keepalived&#xff09;1.Harbor高可用集群部署架构1.1 主机初始化1.1.1 设置网卡名和ip地址1.1.2 设置主机名1.1.3 配置镜像源1.1.4 关闭防火墙1.1.5 禁用SELinux1.1.6 设…

SpringBoot 自定义映射规则resultMap association一对一

介绍 例&#xff1a;学生表&#xff0c;班级表&#xff0c;希望在查询学生的时候一起返回该学生的班级&#xff0c;而一个实体类封装的是一个表&#xff0c;如需要多表查询就需要自定义映射。 表结构 班级表 学生表 SQL语句 SELECT a.id,a.name,a.classes,b.id classes…

Charles抓包 - 安装、激活、证书配置

最近刚好又遇到了抓包的需求&#xff0c;之前一直使用 Fiddler 抓包&#xff0c;这几年一直听大家都在用 Charles 抓包&#xff0c;正好一起了解下&#xff08;一般建议掌握一种抓包方式即可&#xff0c;都可以解决同种需求场景&#xff09; 抓包 Fiddler抓包 Charles 下载、安…

[机器视觉]halcon应用实例 多ROI模板匹配

本示例是单ROI的功能扩展示例&#xff0c;多ROI.后面有空了将出用户自定义ROI。 比单ROI增加ROI区域的连接和合并。还有for的实例应用。步骤同单ROI一样。不懂的可以看一下单ROI文章。[机器视觉]halcon应用实例 单ROI模板匹配-CSDN博客 有需要的可以【点赞】【关注】【收藏】…

2024年新提出的算法|LEA爱情进化算法(Love Evolution Algorithm)

Love Evolution Algorithm: a stimulus–value–role theory-inspired evolutionary algorithm for global optimization 爱情进化算法Love Evolution Algorithm&#xff0c;LEA&#xff0c;于2024年2月发表在中科院3区SCI期刊 The Journal of Supercomputing。 1、简介 本文提…

幸运星数(爷再也不想用pow了)

解法&#xff1a; 暴力 #include <iostream> #include <vector> using namespace std; #define endl \nint main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int n;long long sum 0, a;cin >> n;for (int i 1; i < n; i) {a 1;for (in…

#python升级#CentOS 7 python升级到3.11.6

在 CentOS 7 上升级 Python 版本可能会比较复杂&#xff0c;因为 CentOS 7 默认安装的是 Python 2.7&#xff0c;并且系统很多组件依赖于它。不过&#xff0c;可以通过以下步骤尝试升级到 Python 3.11.6&#xff1a; 安装必要的依赖&#xff1a; sudo yum install gcc openssl-…

洛谷P1015回文数

题目描述 若一个数&#xff08;首位不为零&#xff09;从左向右读与从右向左读都一样&#xff0c;我们就将其称之为回文数。 例如&#xff1a;给定一个十进制数 5656&#xff0c;将 5656 加 6565&#xff08;即把 5656 从右向左读&#xff09;&#xff0c;得到 121121 是一个…