0长度数组的使用,重点掌握的知识

2023-05-16

0长度的数组在ISO C和C++的规格说明书中是不允许的,但是GCC的C99支持的这种用法。
GCC对0长度数组的文档参考:“Arrays of Length Zero”

如下代码片段,哪个更简洁更灵活,看一眼就知道了:

#include <stdlib.h>
#include <string.h>
 
typedef struct tagArray  
{
   int length;
   char contents[]; //这个成员必须是结构体的最后一个成员。
}ARRAY_S;

typedef struct tagPointer
{
    int length;
    char *contents;
}POINTER_S;
 
int main()
{
    int array_length = 10;
    ARRAY_S *pArray  = (ARRAY_S*)malloc (sizeof(ARRAY_S) + array_length);
    POINTER_S *pPointer = NULL;

    if (NULL == pArray)
    {
        return 0;
    }

    pArray->length = array_length;
    memset(pArray->contents, 'a', array_length);

    free(pArray);

    pPointer = (POINTER_S*)malloc(sizeof(POINTER_S));
    if(pPointer == NULL)
    {
        return 0;
    }
    memset(pPointer, 0, sizeof(POINTER_S));
    pPointer->length = array_length;
    pPointer->contents = (char*)malloc(array_length);
    if (pPointer->contents == NULL)
    {
        free(pPointer);
        return 0;
    }
    memset(pPointer->contents, 'a', array_length);

    free(pPointer->contents);
    free(pPointer);

    return 0;
}
第一种结构体的定义:想给一个结构体内的数据分配一个连续的内存,有两个好处:

(1)方便内存释放。
如果我们的代码提供给别人使用,你在里面做了二次内存分配,并把整个结构体返回给用户。
用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。
所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

(2)有利于访问速度。
连续的内存有益于提高访问速度,也有益于减少内存碎片。

第二种结构体的使用:需要分配两次内存以及释放两次内存,在检查申请内存成功与否的代码量上看也明显没有第一种更简洁。

 

 

看看内存是怎么个连续的,用gdb的x命令来查看:(ARRAY_S中的那个char contents[]不占用结构体的内存,
所以ARRAY_S就只有一个int成员,4个字节,而我们还要为contents[]分配10个字节长度,所以,一共是14个字节):

 

 1 (gdb) p pArray 
 2 $1 = (ARRAY_S *) 0x804b008
 3 (gdb) p *pArray 
 4 $2 = {length = 10, contents = 0x804b00c "aaaaaaaaaa"}
 5 (gdb) p pArray ->contents 
 6 $3 = 0x804b00c "aaaaaaaaaa"
 7 (gdb) x/14b pArray 
 8 0x804b008:      10      0       0       0       97      97      97      97
 9 0x804b010:      97      97      97      97      97      97
  从上面的内存布局我们可以看到,前4个字节是 int length,后10个字节就是char contents[]。

  如果用指针的话,会变成这个样子:
10 (gdb) p pPointer 
11 $4 = (POINTER_S *) 0x804b020
12 (gdb) p *pPointer 
13 $5 = {length = 10, contents = 0x804b030 "aaaaaaaaaa"}
14 (gdb) p pPointer ->contents 
15 $6 = 0x804b030 "aaaaaaaaaa"
16 (gdb) x/16b pPointer 
17 0x804b020:      10      0       0       0       48      -80     4       8
18 0x804b028:      0       0       0       0       17      0       0       0
19 (gdb) x/10b pPointer ->contents 
20 0x804b030:      97      97      97      97      97      97      97      97
21 0x804b038:      97      97
22 (gdb) x/16x pPointer 
23 0x804b020:      0x0a    0x00    0x00    0x00    0x30    0xb0    0x04    0x08
24 0x804b028:      0x00    0x00    0x00    0x00    0x11    0x00    0x00    0x00

    第17行前四个字节是 int length,后四个字节是contents的地址。
    第23行以16进制显示,地址是: 0x30 0xb0 0x04 0x08, 即:0x0804b030。
    第20行和第21行是char* contents指向的内容。

    因此,可以看出其中的差别:数组的原地就是内容,而指针的那里保存的是内容的地址。

疑问

       为什么不使用指针来代替零长度数组:

大家在各种场合,可能常常会看到这样的字眼:数组名在作为函数参数进行参数传递时,就相当于是一个指针。在这里,我们千万别被这句话迷惑了:数组名在作为函数参数传递时,确实传递的是一个地址,但数组名绝不是指针,两者不是同一个东西。数组名用来表征一块连续内存存储空间的地址,而指针是一个变量,编译器要给它单独再分配一个内存空间,用来存放它指向的变量的地址。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

0长度数组的使用,重点掌握的知识 的相关文章

  • Duktape:一个新的小巧的超精简可嵌入式JavaScript引擎

    原文链接 xff1a http ourjs com detail duktape E4 B8 80 E4 B8 AA E6 96 B0 E7 9A 84 E5 B0 8F E5 B7 A7 E7 9A 84 E8 B6 85 E7 B2 B
  • 解析物联网三大实时协议

    解析物联网三大实时协议 2015 08 25 国家物联网标识管理公共服务平台 实时通信技术作为一项根本性前提 xff0c 在物联网应用程序的开发工作中扮演着核心角色 想象一下 xff0c 如果我们能够利用手机与家居环境内的各种小装置进行通信
  • stm32低功耗定时器lptimer在djyos下的应用

    djyos的tickless模式配合低功耗模块可以支持传感器之类功耗要求极端苛刻的应用 xff0c djyos的系统时基如果能用stm32的lptimer来提供 xff0c 堪称妙绝 xff0c APP就可以做到完全不用操心功耗 xff0c
  • 一起学djyos-罗侍田-专题视频课程

    一起学djyos 2195人已学习 课程介绍 djyos是国内原创的开源操作系统 xff0c 采用类BSD许可证 经历13年的时间考验 xff0c 可靠性高 xff0c 实时性高 xff0c 功能强大 xff0c 广泛用于电力系统 自动控制
  • C#中十进制与十六进制之间的转换

    一 十进制转换为十六进制 int a 61 654 string A 61 a ToString 34 X6 34 上面Tostring 34 X6 34 是将整型a转化成16进制数 xff1b 其中 xff1a xff08 1 xff09
  • RS485波形记录与分析

    异步串行数据的一般格式是 xff1a 起始位 43 数据位 43 停止位 xff0c 其中起始位1 位 xff0c 数据位可以是5 6 7 8位 xff0c 停止位可以是1 1 5 2位 对于正逻辑的TTL电平 xff0c a 起始位是一个
  • 电脑作为服务器+数据库环境构建以及VS中C#远程连接数据库

    一 将作为服务器的电脑连接网络 xff08 以下简称 服务器 xff09 xff0c 查询服务器的ip地址 方法 xff1a cmd命令ipconfig中IPv4地址就是服务器的ip地址 二 测试服务器和用户电脑 xff08 就是另一台电脑
  • t和printf的缓冲机制

    众所周知 xff0c cout和buffer都是有缓冲的 网上很多把cout和printf混用出错归结为一个有缓冲 xff0c 一个无缓冲 xff0c 事实会在下面说明 cout和printf的输出是先从右往左读入缓冲区 xff0c 再从t
  • 天神降临,大家过来膜拜吧! FLASH AS 3.0 A星(A*, A star) 寻路算法--史上最快,极限优化挑战!

    天神降临 xff0c 大家过来膜拜吧 oh yeah 转载请声明出处 xff0c 例子代码可以免费随意使用 xff0c 但请保留或注明作者信息 这里的算法说是终极优化 我挑战了一下 http eidiot net 2007 04 17 a
  • redis master和slave主备切换,可能导致数据丢失,如何解决?

    1 两种数据丢失的情况 2 解决异步复制和脑裂导致的数据丢失 1 两种数据丢失的情况 主备切换的过程 xff0c 可能会导致数据丢失 xff08 1 xff09 异步复制导致的数据丢失 因为master gt slave的复制是异步的 xf
  • C:基于可以自动扩展缓冲区的stringbuffer,实现内存格式化输出(bufprintf)

    最近做一个C语言的嵌入式项目 xff0c 需要分段向指定内存调用vsnprintf输出不定长度的格式化输出 xff0c 因为是分段输出 xff0c 而且长度不定 xff0c 所以一开始就不能分配固定长度内存 xff0c 每次输出都要从输出到
  • Gitblit服务器搭建及Git使用

    使用Gitblit搭建属于公司或自己的Git服务器 xff0c 方便公司或自己程序代码及文档版本管理 环境 xff1a 1 Win10 64位操作系统 2 Git 2 24 1 2 64 bit xff08 git工具 xff09 3 To
  • C语言中int到float的强制类型转换

    最近在看一本名为的书 由于我所看过的计算机理论方面的书较少 xff0c 加上自己大学期间一直也不用功 xff0c 所以对于计算机的工作原理以及程序的工作方式我始终只知甚少 xff0c 印象也十分模糊 不过 xff0c 应该说我碰到了一本好书
  • 非常实用的一键开关机电路

    按键电路在我们的电路设计中非常常见 xff0c 其中有一种比较特殊 xff0c 就是一键开关机电路 xff0c 顾名思义 xff0c 就是只用一个按键实现开机关机以及其他功能 xff0c 其实大家都接触过 xff0c 我们手机中的开机键就是
  • 一个很精妙的高精度电压基准电路

    先上图 xff0c 图里面的431也可以是别的基准源 xff08 比如LT1004之类的 xff09 甚至可以是一个简单的稳压二极管 需要说明的时 xff0c 此电路并非本人原创 xff0c 也不知道作者是谁 xff0c 偶然看到后 xff
  • AD拼板技巧

    随着整个电子产业的不断发展 xff0c 电子行业的很多产品都已经有完善的上下游配套企业 从一个成熟产品的方案设计 xff0c 外观设计 xff0c 加工制造 xff0c 装配测试 xff0c 包装 xff0c 批发商渠道等等 xff0c 这
  • 单片机RS485通信接口、控制线、原理图及程序实例

    RS232 标准是诞生于 RS485 之前的 xff0c 但是 RS232 有几处不足的地方 xff1a 接口的信号电平值较高 xff0c 达到十几 V xff0c 使用不当容易损坏接口芯片 xff0c 电平标准也与TTL 电平不兼容 传输
  • AD圆形铺铜技巧

    1 在铺铜时按shift 43 空格是可以画圆弧 xff0c 但那只能画一个很小的圆 xff0c 可以用 34 34 34 34 xff08 逗号 xff0c 句号键 xff09 来调整圆的半径 选择铺铜命令 gt 设置参数 gt 进入铺铜
  • 解决STM32 I2C接口死锁在BUSY状态的方法讨论

    解决STM32 I2C接口死锁在BUSY状态的方法讨论 关于STM32的I2C接口死锁在BUSY状态无法恢复的现象 xff0c 网上已有很多讨论 xff0c 看早几年比较老的贴子 xff0c 有人提到复位MCU也无法恢复 只有断电才行的状况

随机推荐

  • 解决AD不能导入CAD文件

    相信好的小伙伴在导入Auto CAD文件时出现下面图片所示的文件后缀 xff0c 且只有这一种 xff1a 那怎么解决呢 xff1f xff1f xff1f 这是因为你没有安装插入的插件而已 xff0c 实际上这是由于新的安装机制导致 xf
  • do{...}while(0)的用法,超详解

    转载原文地址 xff1a http blog csdn net majianfei1023 article details 45246865 零 导引 第一次见到 do while 0 是在学习libevent的时候 xff0c 看到里面有
  • 以太坊的Ethash算法

    Ethash认真的阅读 xff0c 理解 xff0c 计算和调试了一番 xff0c 顺便自己翻译了一下 xff0c 共同学习 此规范是修订版23 Ethash 是 Ethereum 1 0 的计划的PoW算法 这是最新版本的Dagger H
  • MinGW下载

    下载地址 https www mingw w64 org downloads 选择windows版本 点击MingW W64 builds进入页面 https www mingw w64 org downloads mingw builds
  • 关于c语言中printf的几个问题

    问题在执行下列代码时发现的 int main int a 61 1 float b 61 1 0 float c 61 a 10 printf 34 d 34 int b printf 34 d 34 b 问题一 为什么不一样啊 用 d输出
  • 北斗定位与GPS定位的区别

    欢迎来到东用小知识课堂 xff0c 每天学习一分钟 xff0c 让你紧跟时代 xff0c 扩充自己 xff0c 成为大佬不是梦 xff01 1 覆盖范围 xff1a 北斗定位系统是覆盖中国本土的区域导航系统 覆盖范围东经约70 一140 x
  • 污水处理远程监控系统解决方案

    一 行业背景 随着我国科技和经济的发展 xff0c 近年来工厂数量日益增多 xff0c 而生产所带来的工业垃圾及污水就是一个重要的环境污染问题 xff0c 部分工厂甚至会在监管部门的监控死角下偷偷进行污水排放 xff0c 对周围水质造成严重
  • 5G工业路由器安全性怎么样?工业路由器的特点

    路由器 xff0c 本身就是一个具有相当大潜力的网络通信设备 xff0c 即使再是网络小白的用户 xff0c 可能也知道路由器是家中用于发布无线网络的设备 xff0c 如果深入了解的话 xff0c 其作用和发展会让人大为感慨 相信很多用户也
  • 路由器有防火墙?工业路由器的那些安全防护

    想要网络安全光是电脑装了杀毒软件可不行 xff0c 如果一个企业或者大型工厂一旦因为网络防护疏忽 xff0c 那么丢失数据信息所造成的损失是无法估量的 xff0c 所以企业及工厂网络通信及数据传输所使用的路由器一般都是工业级的 xff0c
  • Cat.1和Cat.4有哪些区别

    Cat 1的全称为LTE UE Category 1 xff0c 它是4G LTE网络的一个类 xff0c 也可以理解为低配的4G终端 xff0c 属于广域网 xff0c 蜂窝联网 xff0c 上行峰值为5Mbit s xff0c 下行峰值
  • RS485接口连接设备数量总共有多少?

    RS485总线可以连接256个设备 xff0c 但测试后发现这个数字有比较大的差异 有一种说法认为专门开发串行嵌入式的RS485总线只能连接32个节点 xff0c 这由自身的驱动能力决定的 有人说网上的各种485总线产品可以支持128个 x
  • 预防山体滑坡,泥石流监测智能预警系统

    一 行业背景 我国是一个山区面积较大的国家 xff0c 山地 丘陵约占国土总面积的2 3 xff0c 在众多的山区中 xff0c 都具备泥石流形成的基本条件 xff0c 这也让我国成为受泥石流灾害影响最大的国家 在我国境内 xff0c 泥石
  • 如何扩大无线网络信号强度?

    欢迎来到东用小知识课堂 xff0c 每天学习一分钟 xff0c 让你紧跟时代 xff0c 扩充自己 xff0c 成为大佬不是梦 xff01 无线网络通信设备存在一个问题 xff0c 那就是他的信号发射都是直线型 xff0c 因此一旦家中或者
  • OpenWrt 添加cpu温度显示监控

    opkg update opkg install lm sensors lm sensors detect 然后修改一下 usr lib lua luci view admin status index htm 增加一个温度的显示 lt C
  • RS485接线方式小科普

    欢迎来到东用知识小课堂 xff01 RS 485采用平衡发送和差分接收方式实现通信 xff1a 发送端将串行口的ttl电平信号转换成差分信号a xff0c b两路输出 xff0c 经过线缆传输之后在接收端将差分信号还原成ttl电平信号 RS
  • 传输数据稳如老狗,还支持多种接口,这款DTU让智能化更简单

    如果你的项目正在向着智慧化转变或发展 xff0c 那么你一定会深刻意识到数据传输的稳定性对于整个系统的稳定运行的重要性 毕竟 xff0c 项目的智能化发展需要时刻保持数据的可靠性和稳定传输 xff0c 如果一旦传输因设备或者网络等因素导致中
  • 什么是光耦隔离?光耦隔离的主要作用

    欢迎来到东用知识小课堂 xff01 光耦合器的结构相当于把发光二极管和光敏三极管封装在一起 光耦隔离电路使被隔离的两部分电路之间没有电的直接连接 xff0c 主要是防止因有电的连接而引起的干扰 xff0c 特别是低压的控制电路与外部高压电路
  • ORB305与CISCO路由器构建L2TP over IPSec VPN操作手册

    1 网络拓扑 在思科路由器与ORB305之间建立一个安全隧道 xff0c 对客户路由器端设备子网 xff0c 与思科路由器端服务器子网之间的数据流进行安全保护 xff0c 组网拓扑图如图所示 2 思科路由器端配置指导 此处以多数客户使用专线
  • linux下使用UDP发送接收数据

    接收 static int sock fd struct sockaddr in recv addr 读取参数 struct sockaddr in send addr 发送参数 sock fd 61 socket AF INET SOCK
  • 0长度数组的使用,重点掌握的知识

    0长度的数组在ISO C和C 43 43 的规格说明书中是不允许的 xff0c 但是GCC的C99支持的这种用法 GCC对0长度数组的文档参考 xff1a Arrays of Length Zero 如下代码片段 xff0c 哪个更简洁更灵