【Linux C小技巧】零长度数组的使用
本期主题:
讲清Linux C的零长度数组使用,内容包括:
- 零长度数组是什么原理
- 为什么要使用零长度数组
- 与指针的差异
往期链接:
- 数据结构系列——先进先出队列queue
- 数据结构系列——栈 stack
- Linux内核链表
目录
- 0.前言
- 1.零长度数组原理
- 2.零长度数组特点1:不占空间
- 3.零长度数组特点2:分配的空间可以连续
0.前言
有时候我们在看代码时,会有这种结构体,定义了一个数组长度为0的数组,如下面代码,我初次看见时非常疑惑,那么零长度数组的意义是什么呢?
typedef struct {int a;uint8_t c[0];
} test_a;
1.零长度数组原理
- 长度为0的数组在标准c和c++中是不允许的,如果使用长度为0的数组,编译时会产生错误,提示数组长度不能为0
- 但在GNU C中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理
2.零长度数组特点1:不占空间
看下面这段代码:设计一个包含零长度数组的结构体test_a,还有一个包含指针的结构体test_c
#include <stdio.h>
#include <stdint.h>
#include <string.h>typedef struct {int a;uint8_t c[0];
} test_a;typedef struct {int b;
} test_b;/*这里使用packed,是因为我编译环境是64位*如果不用packed,担心影响大家判断*/
typedef struct {int c;uint8_t *ptr;
} __attribute__ ((packed)) test_c;int main(void)
{test_a a;test_b b;test_c c;printf("sizeof test_a: %ld, sizeof test_b: %ld, sizeof test_c: %ld\n",sizeof(a), sizeof(b), sizeof(c));return 0;
}
测试结果:
$ ./a.out
sizeof test_a: 4, sizeof test_b: 4, sizeof test_c: 12
结论:
可以看出,零长度数组是不占用空间的,这是它优于指针的一个点
3.零长度数组特点2:分配的空间可以连续
设想一个这样的场景,需要设计发送消息的代码,消息包括消息头和payload字段,有两种设计方式:
typedef struct {msg_head_t msg_head;uint8_t data[0];
} msg_t;typedef struct {msg_head_t msg_head;uint8_t *data;
} msg_t;
你觉得哪种更好?
从底层发送接口的角度来考虑,设计函数时,有一个消息的整体指针作为入参就可以了,所以当然是第一种数据连续的底层更好适配。这是零长度数组的第二个特点,比指针更为灵活,空间连续
看测试代码:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>typedef struct _msg_a {int len;uint8_t data[0];
} msg_a_t;typedef struct _msg_b {int len;uint8_t *data;
} msg_b_t;int main(void)
{int data_len = 10;msg_a_t *ptr_msg_a = (msg_a_t *)malloc(sizeof(msg_a_t) + data_len);msg_b_t *ptr_msg_b = (msg_b_t *)malloc(sizeof(msg_b_t));ptr_msg_b->data = malloc(data_len);printf("a: %p, a_data: %p, b: %p, b_data: %p\n",ptr_msg_a, ptr_msg_a->data, ptr_msg_b, ptr_msg_b->data);return 0;
}
结果:
$ ./a.out
a: 0x560958fb1260, a_data: 0x560958fb1264, b: 0x560958fb1280, b_data: 0x560958fb12a0
能看出零长度数组确实是连续空间,符合预期。
参考自 嵌入式C语言自我修养 05:零长度数组
相关文章:
【Linux C小技巧】零长度数组的使用
本期主题: 讲清Linux C的零长度数组使用,内容包括: 零长度数组是什么原理为什么要使用零长度数组与指针的差异 往期链接: 数据结构系列——先进先出队列queue数据结构系列——栈 stackLinux内核链表 目录 0.前言1.零长度数组原理…...

github 网页显示不全?
问题 解决 1、检查网页,打开 network,重新刷新 github 网页 2、查看无法加载的资源(如 css 文件) 3、查看域名地址 https://tool.chinaz.com/dns/,github.githubassets.com(检查网页元素,点击无…...
寄存器介绍
目录 寄存器的概念 寄存器工作原理 寄存器的状态 查看寄存器信息 寄存器复位 大空间寄存器复位 寄存器的概念 寄存器是计算机中一种临时存储数据的硬件设备,通常是高速缓存的一部分,用于存储、读取和操作计算机内部的数据。它们是计算机中最快的存…...

基于CNN-LSTM的时序预测MATLAB实战
一、算法原理 1.1 CNN原理 卷积神经网络具有局部连接、权值共享和空间相关等特性。卷积神经网络结构包含卷积层、激活层和池化层。 (a)二维卷积层将滑动卷积滤波器应用于输入。该层通过沿输入垂直和水平方向 移动滤波器对输入进行卷积,并计…...

MySQL高可用九种方案
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址[1] 参考视频[2] MMM 方案(单主) MySQL 高可用方案之 MMM(Multi-Master Replication Manager&#x…...
react 通过ref 获取对应 dom 的位置信息
需求: 在点击某个dom 元素的时候滚动条要同步滚动 进程: 获取ref 打印,打印出来是一个dom 元素,看不到有什么方法查找 dom 属性信息找到了两个参数,offsetLeft:返回元素的水平偏移位置。 offsetTop&…...

SpringSecurity学习 - 认证和授权
一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。 一般Web应用的需要进行认证和授权。 认证:验证当前访问系统的是不是本系统的用户,并且要…...

JDK jps命令复习
之前写过jdk命令工具的博文,下面复习jps命令; jps 是 Java Process Status Tool 的简称,它的作用是为了列出所有正在运行中的 Java 虚拟机进程和相关信息; jps 命令参数 -q 只输出进程 ID,省略主类的名称 -m 输出虚拟机进程启动时传递…...
Android 13.0 屏蔽Launcher3桌面app图标的长按功能
1.概述 在13.0的产品定制化开发中,系统默认的Launcher3在workspace 第二屏通常都会显示app列表 点击进入app 列表页,长按app的icon图标会弹出 应用信息 弹窗 等信息,而产品的开发需要,不需要弹出这些信息,所以要求去掉app的icon图标的长按功能 2.屏蔽Launcher3桌面app图…...

软考和PMP哪个含金量更高?
软考中,能和pmp一起来比较的是软考高项,软考高级信息系统项目管理师,和PMP的共同点,基本来说都是项目管理类的证书。本质也都是适用于项目经理岗位的证书,软考高项中大部分考试内容是PMPIT技术两部分,其中项…...

第一章:最新版零基础学习 PYTHON 教程(第三节 - 下载并安装Python最新版本)
在这里,我们将讨论如何获得与在 Windows/Linux/mac OS 上安装 Python 相关的所有问题的答案。Python由Guido van Rossum于20世纪90年代初开发,最新版本为3.11,我们可以简称为Python3。 如何下载并安装Python? 要了解如何安装 P…...

Spring 中三种 BeanName 生成器!
无论我们是通过 XML 文件,还是 Java 代码,亦或是包扫描的方式去注册 Bean,都可以不设置 BeanName,而 Spring 均会为之提供默认的 beanName,今天我们就来看看 Spring 中三种处理不同情况的 beanName 生成器。 1. BeanN…...
Go基础-文件、字符
文件创建 导入“os”包,创建文件,读写文件的函数都在改包。 指定创建的文件存放路径以及文件名。 执行Create( )函数,进行文件创建。 关闭文件。 package mainimport ("fmt""os" )func main() {//创建文件,…...

启动YOLO进行图片物体识别
查看官方文档YOLO: Real-Time Object Detection 这些是一些模型的对比,显示了YOLO的优势,继续往下面看 CoCoData set 是一个数据库,用来训练模型,这里面有丰富的物体检测,分割数据集,图像经过了精确的segm…...

BMS电池管理系统的蓝牙芯片 国产高性能 低功耗蓝牙Soc芯片PHY6222
电池管理系统是对电池进行监控与控制的系统,将采集的电池信息实时反馈给用户,同时根据采集的信息调节参数,充分发挥电池的性能。但是,前技术中,在管理多个电池时,需要人员现场调试与设置,导致其…...

肖sir__mysql之三表__008
mysql之三表 create table student( stu_no int, stu_name varchar(10), sex char(1), age int(3), edit varchar(20) ) DEFAULT charsetutf8; insert into student values (1,‘wang’,‘男’,21,‘hello’), (2,‘小明’,‘女’,22,‘haha2’), (3,‘hu’,‘女’,23,‘haha3…...

【Linux】常用工具(上)
Linux 常用工具 一、Linux 软件包管理器 yum1. 软件包2. 查看软件包3. 安装/卸载软件4. yum 其他指令的功能 二、Linux 编辑器 - vim 使用1. vim 的基本概念2. vim 的基本操作(1)光标移动(命令模式)(2)光标…...

【kafka】可视化工具KAFKA EAGLE安装分享
目录 准备: 开始: 1.解压 2.环境变量配置 3.生效环境变量配置文件 3.修改配置文件 1.修改zookeeper集群信息 2.修改mysql配置信息 4.启动 5.异常排查 6.页面 创作不易,你的动力是我创作的动力,如果有帮助请关注我&…...

【深度装机】深度U盘装机后黑屏闪光标
装x64的系统 装机版的gho文件太多预装软件了。几年前买的这种无风扇的机器,之前装的ubuntu:装机U盘启动后,先删掉的所有的ubuntu分区。使用了10几年的AOC又肩负使命: 感觉发热还是挺大的。 有人说因为secure boot 打开secure boo…...

【性能测试】JMeter:集合点,同步定时器的应用实例!
一、集合点的定义 在性能测试过程中,为了真实模拟多个用户同时进行操作以度量服务器的处理能力,可以考虑同步虚拟用户以便恰好在同一时刻执行操作或发送请求。 通过插入集合点可以较真实模拟多个用户并发操作。 (注意:虽然通过加入集合点可…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...