【C语言】柔性数组(可边长数组)
一、介绍
柔性数组(Flexible Array),又称可变长数组。一般数组的长度是在编译时确定,而柔性数组对象的长度在运行时确定。在定义结构体时允许创建一个空数组(例如:arr [ 0 ] ),该数组的大小可在程序运行过程中按照你的需求变动。
struct S
{int n;int arr[0]; // 柔性数组成员
};// 有些编译器会报错无法编译可以改成:struct S
{int n;int arr[]; // 柔性数组成员
};
柔性数组(Flexible Array),是在C语言的 C99 标准中,引入的新特性。结构中的最后一个元素的大小允许是未知的数组,即为柔性数组。
二、柔性数组的特点
- 结构中的柔性数组成员前面必须至少一个其他成员。
- sizeof 返回的这种结构大小不包括柔性数组的内存。
- 包含柔性数组成员的结构用 malloc () 函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
#include <stdio.h>struct S
{int n; //4int arr[0]; //大小是未知的
}s;int main(){printf("%d\n", sizeof(s)); //4struct S* ps = (struct S*)malloc(sizeof(struct S) + sizeof(int)); // 后面+的大小就是给柔性数组准备的return 0;
}
因为这段空间是 malloc 出来的,所以后面 arr 的空间如果不够可以进行调整。它的大小是可以改变的,这里就体现出了 “柔性” 的意义。
三、柔性数组的使用
// 代码一
#include <stdio.h>
#include <stdlib.h>struct S
{int n;int arr[0];
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + sizeof(int));ps->n = 10;for (int i = 0; i < 10; i++){ps->arr[i] = i;}struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 20*sizeof(int));if (ptr != NULL){ps = ptr;}free(ps);ps = NULL;return 0;
}
这样柔性数组成员 arr ,相当于获得了 10 个整型元素的连续空间。
四、柔性数组的优势
// 代码二
#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 = 10;ps->arr = (int*)malloc(10 * sizeof(int));if (ps->arr == NULL){return 1;}for (int i = 0; i < 10; i++){ps->arr[i];}int* ptr = (struct S*)realloc(ps->arr, 20 * sizeof(int));if (ptr != NULL){ps->arr = ptr;}// 这里需要回收2个空间,且回收必须有先后free(ps->arr); // 先free第二块空间ps->arr = NULL;free(ps);ps = NULL;return 0;
}
上述 代码一 和 代码二 可以完成同样的功能,但是代码一 的实现有两个好处:
- 第一个好处是:方便内存释放。
虽然 代码二实现了相应的功能,但是和 代码一相比还是有很多不足之处的。 代码二使用指针完成, 进行了两次 malloc ,而两次 malloc 对应了两次 free ,相比于 代码一更容易出错。如果我们的代码是在一个给别人用的函数中,你在里面做了两次内存分配,并把整个结构体返回给用户。虽然用户调用 free 可以释放结构体,但是用户并不知道这个结构体内的成员也需要 free,所以你不能指望用户来发现这件事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好(而不是多次分配),并且返回给用户一个结构体指针, 用户只需使用一次 free 就可以把所有的内存都给释放掉,可以间接地减少内存泄露的可能性。
- 第二个好处是:这样有利于访问速度。
连续内存多多少少有益于提高访问速度,还能减少内存碎片。malloc 的次数越多,产生的内存碎片就越多,这些内存碎片不大不小,再次被利用的可能性很低。内存碎片越多,内存的利用率就会降低。频繁的开辟空间效率会变低,碎片也会增加。
相关文章:
【C语言】柔性数组(可边长数组)
一、介绍 柔性数组(Flexible Array),又称可变长数组。一般数组的长度是在编译时确定,而柔性数组对象的长度在运行时确定。在定义结构体时允许创建一个空数组(例如:arr [ 0 ] ),该数…...
C++信息学奥赛1131:基因相关性
这段代码的功能是比较两个字符串的相似度,并根据给定的阈值判断是否相似。 解析注释后的代码如下: #include <iostream> #include <string> using namespace std;int main() {double bf; // 定义双精度浮点数变量bf,用于存储阈…...
如何保证分布式系统中服务的高可用性:应对 ZooKeeper Leader 节点故障的注册处理策略
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 https://dr…...
SQL注入之延时注入
文章目录 延时注入是什么?延时注入获取数据库版本号 延时注入是什么? 延时注入就是利用sleep()函数通过if语句判断所写的语句真假,如果为真返回我们想要的东西(例如:数据库的长度,数据库的名字等࿰…...
运维高级学习--Docker(二)
1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。 #拉取mysql5.6和owncloud镜像 [rootlocalhost ~]# docker pull mysql:5.6 [rootlocalhost ~]# docker pull owncloud [rootlocalhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED …...
QT的核心——信号与槽
目录 回顾C 语言信号 1、信号与槽 2、关联信号与槽 2.1自动关联信号与槽 2.2手动关联信号与槽 2.3断开信号与槽 3、自定义信号 3.1自定义信号使用条件 3.2自定义槽函数使用条件 4、信号与槽参数传递 4.1自定义一个带参的信号 4.2关联带参的信号与槽 4.3发送一个带…...
【业务功能篇73】web系统架构演变-单体-集群-垂直化-服务化-微服务化
1.服务架构的演 1.1 单体架构 单体架构应该是我们最先接触到的架构实现了,在单体架构中使用经典的三层模型,即表现层,业务逻辑层和数据访问层。 单体架构只适合在应用初期,且访问量比较下的情况下使用,优点是性价比很…...
MyCAT命令行监控
9066端口 ,用mysql命令行连接 Mysql –utest –ptest –P9066 show help 可显示所有相关管理命令 显示后端物理库连接信息,包括当前连接数,端口 Show backend Show connection 显示当前前端客户端连接情况,已经网络流量信息、…...
【python】正则表达式匹配数据
前言 使用正则表达式处理数据,可进行字符串匹配、提取和替换等操作。在python中,通过re库完成正则匹配的操作。 一、正则语法规则 1.常用匹配符 模式描述^匹配字符串开头$匹配字符串结尾.匹配任意字符*匹配前面的字符零次或多次匹配前面的字符一次或多…...
【C++】用Windows API在控制台实现选择选项
2023年8月23日,周三上午 今天上午花了一个小时来实现这个 这个程序在碰到边界时会发出声音, 通过调用Windows API的Beep函数来实现。 #include<Windows.h> #include<conio.h> #include<iostream> #include<cstdlib>const int …...
Golang 批量执行/并发执行
提到Golang,都说Golang 天生高并发。所以分享一下我认为的Golang高并发精髓 简单的并发执行util package util import ("context""sync" )type batchRunner struct {BatchSize intctx context.Contextchannel chan func()wg sy…...
使用go语言、Python脚本搭建一个简单的chatgpt服务网站。
使用go语言、Python脚本搭建一个简单的GPT服务网站 前言 研0在暑假想提升一下自己,自学了go语言编程和机器学习相关学习,但是一味学习理论,终究是枯燥的,于是自己弄点小项目做。 在这之前,建议您需要掌握以下两个技…...
基于java会议室预约系统设计与实现
摘要 一个企业的发展离不开相关的规定流程。信息化到来的今天在我们的生活当中。离不开各种信息化的支持。比如钉钉会议预约、美团买菜、扫码签到等各种信息化软件。他们涉及我们生活中的方方面面给我们的生活提供了更大的便利性。大到政府、企业办公小到人们的衣食住行都离不开…...
Ubuntu18.04 交叉编译curl-7.61.0
下载 官方网址是:curl 安装依赖库 如果需要curl支持https协议,需要先交叉编译 openssl,编译流程如下: Ubuntu18.04 交叉编译openssl-1.1.1_我是谁??的博客-CSDN博客 解压 # 解压: $tar -xzvf curl-7.61.…...
Android相机-HAL子系统
引言 应用框架要通过拍照预览摄像获得照片或者视频,就需要向相机子系统发出请求, 一个请求对应一组结果 一次可发起多个请求,并且提交请求是非阻塞的,始终按照接收的顺序以队列的形式先进先出地进行顺序处理 一个请求包含了拍摄和拍照配置的所有信息&…...
PostgreSQL-研究学习-介绍与安装
PostgreSQL-预研 是个很厉害的数据库的样子 ψ(*`ー)ψ 官方文档:http://www.postgres.cn/docs/12/ 总的结论和备注 PgSQL 支持对JSON的支持很强大,以及提供了很多数学几何相关的数据类型【例:点,线条,几何…...
【Unity细节】Unity制作汽车时,为什么汽车会被弹飞?为什么汽车会一直抖动?
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶🌫️收录于专栏:unity细节和bug 😶🌫️优质专栏 ⭐【…...
Android初学之android studio运行java/kotlin程序
第一步骤:File—>New—>New Module,然后弹出一个框,(左边)选择Java or Kotlin Library,(右边)编辑自己的图书馆名、包名、类名,选择Java一个语言,然后F…...
使用自定义 C ++类扩展 TorchScript
使用自定义 C 类扩展 TorchScript 本教程是自定义运算符教程的后续教程,并介绍了我们为将 C 类同时绑定到 TorchScript 和 Python 而构建的 API。 该 API 与 pybind11 非常相似,如果您熟悉该系统,则大多数概念都将转移过来。 在 C 中实现和…...
UITableView自定义TableHeader和TableFooter
UITableView自定义TableHeader和TableFooter 我猜你希望的效果是这样的 我猜你希望的效果是这样的 自定义页眉视图 让我们创建一个文件名 UITableViewHeaderFooterView 的 CustomerHeaderView 子类。 现在让我们创建视图的 Xib 文件并将其命名为 CustomHeaderView。 更改高度标…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
