码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【Linux C小技巧】零长度数组的使用


    本期主题:
    讲清Linux C的零长度数组使用,内容包括:

    1. 零长度数组是什么原理
    2. 为什么要使用零长度数组
    3. 与指针的差异

    往期链接:

    • 数据结构系列——先进先出队列queue
    • 数据结构系列——栈 stack
    • Linux内核链表

    目录

    • 0.前言
    • 1.零长度数组原理
    • 2.零长度数组特点1:不占空间
    • 3.零长度数组特点2:分配的空间可以连续


    0.前言

    有时候我们在看代码时,会有这种结构体,定义了一个数组长度为0的数组,如下面代码,我初次看见时非常疑惑,那么零长度数组的意义是什么呢?

    typedef struct {
    	int a;
    	uint8_t c[0];
    } test_a;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.零长度数组原理

    1. 长度为0的数组在标准c和c++中是不允许的,如果使用长度为0的数组,编译时会产生错误,提示数组长度不能为0
    2. 但在GNU C中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理

    2.零长度数组特点1:不占空间

    看下面这段代码:设计一个包含零长度数组的结构体test_a,还有一个包含指针的结构体test_c

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    测试结果:

    $ ./a.out
    sizeof test_a: 4, sizeof test_b: 4, sizeof test_c: 12
    
    • 1
    • 2

    结论:

    可以看出,零长度数组是不占用空间的,这是它优于指针的一个点

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    你觉得哪种更好?

    从底层发送接口的角度来考虑,设计函数时,有一个消息的整体指针作为入参就可以了,所以当然是第一种数据连续的底层更好适配。这是零长度数组的第二个特点,比指针更为灵活,空间连续
    看测试代码:

    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    结果:

    $ ./a.out
    a: 0x560958fb1260, a_data: 0x560958fb1264, b: 0x560958fb1280, b_data: 0x560958fb12a0
    
    • 1
    • 2

    能看出零长度数组确实是连续空间,符合预期。

    参考自 嵌入式C语言自我修养 05:零长度数组

  • 相关阅读:
    C#中.NET 6.0 Windows窗体应用通过EF访问数据库并对数据库追加、删除记录
    使用hyper-V 编译和调试Android13(android-13.0.0_r3)源码
    【java】【SSM框架系列】【三】Maven进阶
    AWS SAA-C03 #113
    《自然语言处理实战入门》深度学习基础 ---- attention 注意力机制 ,Transformer 深度解析与学习材料汇总
    MT4选网页版还是桌面版?anzo capital昂首资本分析优劣
    【无标题】
    最新发布!阿里云卓越架构框架重磅升级
    【一起读技术书】为什么开始,怎么开始,我们一起开始
    通过R Studio用Markdown写Beamer
  • 原文地址:https://blog.csdn.net/weixin_37620587/article/details/132915468
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号