C语言中长度为0的数组

2023-11-03

前面在看Xen的源码时,遇到了一段代码,如下所示:

注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为的数组?长度为的数组到底怎么使用?……这篇文章主要针对该问题进行简单的讲解。废话不多说了,现在就开始。

长度为的数组在标准cc++中是不允许的,如果使用长度为的数组,编译时会产生错误,提示数组长度不能为。但在GNUc中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理。如果你将上面的长度为的数组换为指针,那么在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。

对于长度为的数组,在gcc手册中,有如下一段代码片段:

struct line {

int length;

char contents[0];

};

struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);

thisline->length = this_length;

这段代码的主要含义是定义了一个结构体,并对其进行初始化,上面结构体的第二个成员变量contents[0]事实上是不占内存空间的,因此整个结构体的长度sizeof(struct line)4。当采用malloc为其申请内存空间时,如上所示,申请了一段长度为结构体长度加可变长度的内存空间给结构体类型的指针,这时contents就指向申请的可变长度的内存空间。由于是一次申请的,所以这段可变长度的内存空间和前面的结构体长度的内存空间是连续的。对于这段可变长度的内存空间,可以采用数组的方式对其进行访问。对于整个结构体,当不再使用时,可以使用free函数一次性对其进行释放,而不必像指针那样分别释放。

下面举例进行说明:

#include <stdio.h>
#include <stdlib.h>
#define LENGTH 10

struct test1
{
int a;
int *b;
}__attribute((packed));

struct test2
{
int a;
int b[0];
}__attribute((packed));

struct test3
{
int a;
int b[1];
}__attribute((packed));

int main()
{
struct test1 *var1;
struct test2 *var2;
struct test3 *var3;
int i;

printf("the length of struct test1:%d\n",sizeof(struct test1));
printf("the length of struct test2:%d\n",sizeof(struct test2));
printf("the length of struct test3:%d\n",sizeof(struct test3));

var1=(struct test1*)malloc(sizeof(struct test1));
var1->a=1;
var1->b=(int *)malloc(sizeof(int));
*var1->b=1;
printf("\nvar1->a=%d,*(var1->b)=%d\n",var1->a,*var1->b);

var2=(struct test2*)malloc(sizeof(struct test2)+sizeof(int)*LENGTH);
var2->a=2;
printf("\nvar2->a=%d\n",var2->a);
for(i=0;i<LENGTH;i++)
{
var2->b[i]=i;
printf("var2->b[i]=%d\t",var2->b[i]);
}
printf("\n\n"); 

var3=(struct test3*)malloc(sizeof(struct test3));
var3->a=3;
(var3->b)[0]=3;
printf("var3->a=%d,(var3->b)[0]=%d\n",var3->a,(var3->b)[0]);


free(var1->b);
free(var1);
free(var2);
free(var3);

}

这段程序的运行结果如下图所示:

从上面的结果可以看出:

长度为的数组并不占有内存空间,而指针方式需要占用内存空间。

对于长度为数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。

对于长度为的数组的访问可采用数组方式进行。

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

C语言中长度为0的数组 的相关文章

  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 显示异常时的自定义错误消息:从客户端检测到潜在危险的 Request.Form 值

    我在我的 Web 应用程序中使用 ASP NET 的登录控件 当发生此异常时 我想在标签上显示一种有趣的错误类型System Web HttpRequestValidationException A potentially dangerou
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 当“int”处于最大值并使用 postfix ++ 进行测试时,代码定义良好吗?

    示例 未定义行为的一个示例是整数溢出的行为 C11dr 3 4 3 3 int溢出是未定义的行为 但这是否适用于存在循环的以下内容 并且不使用现在超出范围的副作用i 特别是 这是否后缀增量规格帮助 结果的值计算在副作用之前排序 更新操作数的
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐

  • java常用部署脚本

    记一个工作中常用的java部署脚本 首先进入linux 1 使用下面代码段 vim run sh 2 然后按 i 进入编辑模式 3 拷贝下面脚本代码 bin sh chkconfig 2345 99 10 description Start
  • 西门子S7-1200 PLC进行项目选型要了解这些

    西门子S7 1200 PLC是西门子S7系列PLC产品中一员 S7系列产品包含有 S7 200 Smart 200 S7 1200 S7 300 S7 1500 S7 400等系列PLC 其中S7 200 Smart 200 S7 1200
  • Java多线程编程详解(第零章)

    Java多线程编程详解 0 参考书籍 Java并发编程实战 Java并发编程实战 本文是关于以上两本书的读书笔记以及一些个人思考 0 关于并发与多线程的简介 编写正确的程序很难 而编写正确的并发程序则难上加难 与串行程序相比 在并发程序中存
  • 如何针对单个表单项去掉验证和添加验证?

    this refs conpanyForm clearValidate district 清除校验 this refs conpanyForm validate district 添加校验
  • Ubuntu安装notepad++

    习惯了Windows的代码编写输入方式 转回Ubuntu vim编程总有点不习惯和不方便 即使vim功能很强大 我还是喜欢Windows的代码编写输入方式 简简单单 安装个notepadqq就行了 Ubuntu版notepad 安装方式 s
  • vue vue-json-viewer 展示 JSON 格式数据

    1 下载 vue json viewer npm 下载 vue json viewer Vue2 npm install vue json viewer 2 save Vue3 npm install vue json viewer 3 s
  • MS Active Accessibility 接口技术编程尝试

    MS Active Accessibility 接口技术编程尝试 编译 崔传凯 下载源代码 Microsoft Active Accessibility 2 0 is a COM based technology that improves
  • 【Ogre编程入门与进阶】第十三章 公告板与粒子系统

    Ogre编程入门与进阶 第十三章 公告板与粒子系统 标签 ogre公告板粒子系统ogre粒子系统 2015 07 05 14 41 1365人阅读 评论 1 收藏 举报 分类 Orge模块 16 版权声明 本文为博主原创文章 未经博主允许不
  • 计算机电源接口图解,菜鸟老鸟都要知道 电源接口图文全教程

    IT168 应用 电源的功率一直是玩家们关注的焦点 可对于刚涉足DIY领域的用户来说 自己组装DIY一台电脑拿才是最令人兴奋的事情 组装电脑少不了要接各种各样的线材 那么如何辨别各种类型的接口 每个接口之间的的功能有何区别呢 电源接口种类繁
  • 微信小程序之分享页面内容为空

    文章目录 错误记录 分享的关键方法 onShareAppMessage 错误记录 分享出去的页面 别人打开没有内容 解决方法参考文章 说是因为分享出去的页面的某些数据是上级页面传递过来的 结果直接分享出去的页面 别人打开是获取不到传递过来的
  • leetcode 二叉树题目总结

    leetcode 二叉树题目总结 一 基本问题 遍历 前序遍历 后序遍历 中序遍历 莫里斯遍历 空间复杂度O 1 层次遍历 由序列构造二叉树 递归解决二叉树问题 将二叉树转换为其他结构 二叉树结构 struct TreeNode int v
  • nrm安装(NPM源管理器)

    1 什么是nrm nrm 是一个 npm 源管理器 允许你快速地在 npm源间切换 npm默认情况下是使用npm官方源 使用命令可以查看 一般我们都会用淘宝npm源 设置淘宝源 npm set registry https registry
  • 智能小车之PWM脉冲控制小车调速

    目录 一 PWM脉冲控制小车调速 二 代码实现 一 PWM脉冲控制小车调速 原理 全速前进是LeftCon1A 0 LeftCon1B 1 完全停止是LeftCon1A 0 LeftCon1B 0 那么单位时间内比如 20ms 有15ms是
  • java keytool 工具

    Keytool 是一个JAVA环境下的安全钥匙与证书的管理工具 Keytool将密钥 key 和证书 certificates 存在一个称为keystore 的文件 受密码保护 中 在keystore里 包含两种数据 密钥实体 Key en
  • 【编程之路】Python编程进阶

    Python编程进阶 不使用中间变量 交换两个变量a和b的值 a b b a 需要注意 a b b a 这种做法其实并不是元组解包 虽然很多人都这样认为 Python 字节码指令中有 ROT TWO 指令来支持这个操作 类似的还有 ROT
  • JAVASE-01:基础概念知识及学习环境配置

    JAVASE 01 基础概念知识及学习环境配置 Java语言发展史 詹姆斯 高斯林 James Gosling 1977年获得了加拿大卡尔加里大学计算机科学学士学位 1983年获得了美国卡内基梅隆大学计算机科学博士学位 毕业后到IBM工作
  • 最新暴力破解漏洞技术详解

    点击星标 即时接收最新推文 本文选自 web安全攻防渗透测试实战指南 第2版 点击图片五折购书 暴力破解漏洞简介 暴力破解漏洞的产生是由于服务器端没有做限制 导致攻击者可以通过暴力的手段破解所需信息 如用户名 密码 短信验证码等 暴力破解的
  • 操作系统的特征

    四个特征 并发 共享 虚拟 异步 一 并发 1 并发概念 指两个或者多个事件在同一时间间隔内发生 这些事件宏观上是同时发生的 但是在微观上是交替发生的 操作系统的并发性是指 计算机系统同时存在着多个运行着的程序 操作系统和程序并发是一起诞生
  • 小米再次翻车!学python一定要看这篇!!

    小米英国官方推特近日发布了一则营销推文 调侃了最近火热的比尔 盖茨离婚事件 推文图片中为信息页面 收件人为梅琳达 信息内容为 我们需要谈谈 而且推文下方显示小尾巴为 iPhone 推文内容为 虽然和你的亿万富翁合作伙伴分手可能不是明智的选择
  • C语言中长度为0的数组

    前面在看Xen的源码时 遇到了一段代码 如下所示 注意上面最后一行的代码 这里定义了一个长度为的数组 这种用法可以吗 为什么可以使用长度为0 的数组 长度为的数组到底怎么使用 这篇文章主要针对该问题进行简单的讲解 废话不多说了 现在就开始