C语言---番外篇(柔性数组)

前言:

        由于这块内容所谓综合性比较高,有数组的知识,有结构体的知识,还有动态内存管理的知识,所以我就单独写一篇博客,此谓番外篇。

柔性数组的概念

        定义在结构体的最后一个元素的位置且大小未知的数组就叫柔性数组。

#include<stdio.h>
#include<stdlib.h>
struct test1
{int n;int arr[];//柔性数组
};struct test2
{int n;int arr[0];//柔性数组
};int main()
{return 0;
}

        以上这两种定义的方式都是柔性数组,但可能有的编译器上并不是两种情况都支持。

柔性数组的特点

        1.柔性数组的成员前边必须要有别的成员。

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

        3.必须要和动态内存分配(malloc函数等)一起结合使用。并且在动态分配内存大小的时候给柔性数组预留大小。

柔性数组的使用

        如果有结构体或者动态内存管理等相关知识不知道的,可以去看一下我写的博客,链接如下。

        C语言---自定义类型(上)(结构体类型)-CSDN博客

        C语言---动态内存管理-CSDN博客

        大家简单看一下我下边的代码(代码1)示例就懂柔性数组的基本使用了。

#include<stdio.h>
#include<stdlib.h>
struct test
{int n;int arr[];
};int main()
{//动态申请空间//前边半部分是给除去柔性数组的其他成员在堆区分配空间,后半部分申请的空间就给到的是结构体struct test* pt = (struct test*)malloc(sizeof(struct test) + 5 * sizeof(int));if (pt == NULL){//进入表示开辟空间失败perror("malloc");return 1;}//使用pt->n = 10;for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空间不够扩容struct test* ptr = (struct test*)realloc(pt, sizeof(struct test) + 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt = ptr;ptr = NULL;//释放空间free(pt);pt = NULL;return 0;
}

        下边来看看内存里边大概是什么样子的

柔性数组的优势

        先来看一下下边的代码(代码2),可以产生与刚才的柔性数组一样的效果。

#include<stdio.h>
struct test2
{int n;int* arr;//arr指针可以指向一块空间
};int main()
{//申请空间//给结构体整体分配空间struct test2* pt = (struct test2*)malloc(sizeof(struct test2));if (pt == NULL){perror("malloc1");return 1;}//使用pt->n = 10;//另外开辟一块空间让arr指针指向它pt->arr = (int*)malloc(5 * sizeof(int));if (pt->arr == NULL){perror("malloc2");return 1;}//使用arr指向的空间for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空间不够扩容int* ptr = (int*)realloc(pt->arr, 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt->arr = ptr;ptr = NULL;//使用................//释放//两次释放,先释放arr指向的空间,再释放结构体的空间free(pt->arr);pt->arr = NULL;free(pt);pt = NULL;return 0;
}

        代码2的内存结构大致如下图

        代码1和代码2有相同的效果,但很明显用代码1会更加好一点,也就是用柔性数组会更好一些,它的优势就是减少了内存碎片,提高访问速度,内存碎片就是指的每次动态内存申请的时候每一块空间之间的被浪费的间隙空间(不理解也没事),用柔性数组最大的好处就是方便内存释放,只需要free一次。

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

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

相关文章

单片机的几种GPIO输入输出模型详解

模式选择汇总参考表&#xff1a;模式输出驱动输入阻抗默认状态典型应用场景推挽输出强驱动禁用可配置LED, SPI, 高速信号开漏输出弱驱动禁用低/悬空IC, 电平转换, 线与浮空输入禁用极高不确定外部强驱动信号上拉输入禁用中高高电平按键(接地型), 数字输入下拉输入禁用中高低电平…

深度解析ECharts.js:构建现代化数据可视化的利器

引言&#xff1a;数据可视化的新时代挑战 在数字化转型浪潮中&#xff0c;数据可视化已成为企业决策和用户体验的关键环节。面对海量数据的呈现需求&#xff0c;传统表格已无法满足用户对直观洞察的渴求。作为百度开源的JavaScript可视化库&#xff0c;ECharts.js凭借其强大的功…

从零构建实时通信引擎:Freeswitch源码编译与深度优化指南

一、构建工具&#xff1a;编译FreeSWITCH及其依赖库的基础 1. CMake2. Autoconf 二、汇编器&#xff1a;提升音视频处理性能 3. YASM / NASM 三、音视频编解码器&#xff1a;支撑实时媒体传输 4. Opus5. x264 (可选)6. libvpx / libvpx2 (可选) 四、多媒体框架与工具库&#xf…

网络原理 HTTP 和 HTTPS

目录 一 . HTTP 协议 二 . 抓包 三 . HTTP 请求 / 响应的基本格式 &#xff08;1&#xff09;HTTP请求的基本格式 &#xff08;2&#xff09;HTTP响应的基本格式 四 . HTTP 方法 GET 和 POST 的区别&#xff1a; 五 . 请求报头和响应报头 &#xff08;1&#…

基于单片机的自动条幅悬挂机

摘 要 随着日新月异科技发展&#xff0c;在心率体温测量方面&#xff0c;我们取得了迅速的发展&#xff0c;就近日而言&#xff0c;脉搏测量仪已经在多个领域大展身手&#xff0c;除了在医学领域有所建树&#xff0c;在人们的日常生活方面的应用也不断拓展&#xff0c;如检疫…

《C++》面向对象编程--类(中)

文章目录一、构造函数1.1定义1.2语法1.3特性二、析构函数2.1定义2.2语法2.3特性三、拷贝构造函数3.1定义3.2语法3.3特性3.4浅拷贝3.4.1定义3.4.2浅拷贝的风险3.5深拷贝一、构造函数 1.1定义 在C中&#xff0c;构造函数&#xff08;Constructor&#xff09; 是一种特殊的成员函…

机器学习初学者理论初解

大家好! 为什么手机相册能自动识别人脸&#xff1f;为什么购物网站总能推荐你喜欢的商品&#xff1f;这些“智能”背后&#xff0c;都藏着一位隐形高手——机器学习&#xff08;Machine Learning&#xff09;。一、什么是机器学习&#xff1f;简单说&#xff0c;机器学习是教计…

原码反码补码

在Java中&#xff0c;无论是小数还是整数&#xff0c;他们都要带有符号&#xff08;和C语言不同&#xff0c;C语言有无符号数&#xff09;。首位就作为符号位。原码反码&#xff1a;正数的反码是其原码本身负数的反码是在其原码的基础上, 符号位不变&#xff0c;其余各个位取反…

使用ubuntu:20.04和ubuntu:jammy构建secretflow环境

一、使用ubuntu:20.04构建隐语编译环境FROM ubuntu:20.04LABEL maintainer"build SecureProtocolLib on ubuntu:20.04"ARG TARGETPLATFORM# change dash to bash as default shell RUN ln -sf /bin/bash /bin/shRUN apt update \&& apt upgrade -y \&&am…

Hinge Loss(铰链损失函数)详解:SVM 中的关键损失函数

&#x1f4cc; 一、什么是 Hinge Loss&#xff1f;Hinge Loss&#xff08;铰链损失&#xff09;&#xff0c;是 支持向量机&#xff08;SVM, Support Vector Machine&#xff09; 中常用的一种损失函数&#xff0c;用于最大间隔分类。其核心思想是&#xff1a;当预测结果已经正…

days32 :零基础学嵌入式之网络2.0

一、wireshark &#xff1a;网络抓包工具1.功能&#xff1a;抓取通过电脑网卡的网络数据2.作用&#xff1a;排查故障、抓取数据做数据分析、3.用法&#xff1a;&#xff08;1&#xff09;sudo wireshark&#xff08;2&#xff09;选择需要抓取的网卡》any&#xff08;3&#xf…

数字护网:一次深刻的企业安全体系灵魂演练

&#x1f9e9; 引言&#xff1a;什么是“护网”&#xff1f;—— 不止是攻防&#xff0c;更是企业安全能力的年度大考 每年&#xff0c;由国家相关部门牵头的“护网行动”都如期而至&#xff0c;各大企事业单位的安全团队也随之进入高度戒备状态。然而&#xff0c;“护网”远非…

基于 NumPy 的高效数值计算技术解析与实践指引

在数据处理与科学计算领域&#xff0c;高效是核心诉求。NumPy 作为 Python 生态高效数值计算的基石&#xff0c;以高性能多维数组对象及配套函数&#xff0c;成为数据从业者的必备工具。其数组支持算术、比较、逻辑等丰富运算&#xff0c;通过向量化操作直接处理每个元素&#…

Kafka MQ 控制器 broker

Kafka MQ 控制器 broker 1 控制器broker的选举 在 Kafka 集群中会有一个或多个 broker,其中有一个 broker 会被选举为控制器(Kafka Controller)​,它负责管理整个集群中所有分区和副本的状态。当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ImageCarousel(图片轮播组件)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— ImageCarousel组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 <script setup> 语法以及 Tailwind CSS …

基于springboot的智能物流管理系统(源码+论文)

一、开发环境 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器&#xff0c;基于SQL的客户/服务器模式的关系数据库管理系统。其特点包括&#xff1a; 功能强大&#xff1a;支持多用户、多线程操作。使用简单&#xff1a;管理方便&#xff0c;安全可靠性高。跨平…

Collection接口的详细介绍以及底层原理——包括数据结构红黑树、二叉树等,从0到彻底掌握Collection只需这篇文章

目录 Collection简介 Collection的遍历方式 迭代器遍历 增强for遍历 Lambda表达式遍历 List集合 List集合的遍历方式 列表迭代器遍历以及普通for循环 数据结构 栈 队列 数组 链表 单向链表 双向链表 二叉树 遍历方式 普通二叉树 二叉查找树 平衡二叉树 旋转…

《安顺棒垒球》世界十大运动·棒球1号位

Worlds Top 10 Sports for Newbies | 棒球排第几&#xff1f; 全球青训体系大揭秘 ⚾添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;神王棒球世界十大运动排名 Top 10 Global Sports&#xff08;按参与度/商业价值/影响力综合排序&#xff09;足球 Footba…

什么是“差分“?

1. 什么是"差分"&#xff1f;想象两个人在玩跷跷板&#xff1a;当两人同时向上跳&#xff08;同向移动&#xff09;→ 跷跷板不动 → 这叫"共模"当一人向上&#xff0c;另一人向下&#xff08;反向移动&#xff09;→ 跷跷板倾斜 → 这叫"差分"差…

4.组合式API知识点(2)

10 组合式API - 模版引用模板引用的概念如何使用&#xff08;以获取dom为例 组件同理&#xff09;组件实例对象defineExpose()11 组合式API - provide和inject作用和场景跨层传递普通数据跨层传递响应式数据跨层传递方法需求解决思考