【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:集合点,同步定时器的应用实例!
一、集合点的定义 在性能测试过程中,为了真实模拟多个用户同时进行操作以度量服务器的处理能力,可以考虑同步虚拟用户以便恰好在同一时刻执行操作或发送请求。 通过插入集合点可以较真实模拟多个用户并发操作。 (注意:虽然通过加入集合点可…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
