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

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

长度为的数组在标准c和c++中是不允许的,如果使用长度为的数组,编译时会产生错误,提示数组长度不能为。但在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);

}

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

从上面的结果可以看出:

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

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

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

C语言长度为0的数组相关推荐

  1. 【嵌入式】C语言高级编程-长度为0的数组(05)

    00. 目录 文章目录 00. 目录 01. 什么是零长度数组 02. 零长度数组应用 03. 内核中的零长度数组 04. 指针可以代替零长度数组? 05. 附录 01. 什么是零长度数组 零长度数组 ...

  2. C语言中长度为0的数组

    前面在看Xen的源码时,遇到了一段代码,如下所示: 注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0 的数组?长度为的数组到底怎么使用?--这篇文章主要针对该 ...

  3. C语言技巧之长度为0的数组

    在gnu c中有一种用法,就是可以使用长度为0的数组,比如说一下这个结构体: struct sample { int length; char store[0]; } 可以像以下这种方式来使用: st ...

  4. GNU C的定义长度为0的数组

    原文地址:http://blog.csdn.net/ssdsafsdsd/article/details/8234736 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个 ...

  5. C/C++ 中长度为0的数组

    参考文献:http://blog.csdn.net/zhaqiwen/article/details/7904515 近日在看项目中的框架代码时,发现了了一个奇特的语法:长度为0的数组例如 uint8 ...

  6. java数组长度为0和数组为null

    长度为0的数组,可以求数组长度,为0,即数组内没有元素. int[] zero = new int[0]; //zero引用一个长度为0的数组对象 为null的数组,不能求数组长度,且求解时会出现空指 ...

  7. 【C语言】关于结构体最后的长度为0或1数组的思考

    需要引起注意的:ISO/IEC 9899-1999里面,这么写是非法的,这个仅仅是GNU C的扩展,gcc可以允许这一语法现象的存在.但最新的C/C++不知道是否可以,我没有测试过.(C99允许.微软 ...

  8. 一万字详解C语言中长度为零的数组

    点击蓝字 关注我们 零长度数组概念: 众所周知, GNU/GCC 在标准的 C/C++ 基础上做了有实用性的扩展, 零长度数组(Arrays of Length Zero) 就是其中一个知名的扩展. ...

  9. C/C++ 中的0长数组(柔性数组)

    C/C++ 中的0长数组(柔性数组) 在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的. 但是,GUN中却允许使用,而且,很多时候,应用在了变 ...

最新文章

  1. Go 学习笔记(68)— goroutine 并发控制神器 Context
  2. 百度王海峰:多模态深度语义理解将让AI更深地理解真实世界
  3. 真我新格调 勇敢使梦想×××
  4. 深入了解android平台的jni---注册native函数
  5. 如何在SQL中使用JOIN执行UPDATE语句?
  6. 写给初学者的Tensorflow介绍
  7. CSDN转载博客的方法
  8. yii2的Console定时任务创建
  9. 微软2011 GCR MVP Open Day 之旅!
  10. 微搭低代码中实现数据的联动选择
  11. word一键生成ppt 分页_一键实现Word转PPT的三种方法评测
  12. Adobe Premiere基础-时间重映射(十)
  13. Google analytics如何统计网站信息?
  14. 超有用:记一次Yapi上传报错及其处理方式
  15. 图片放大模糊怎么办,Python无损清晰放大,360P变4K
  16. 如何成为全栈工程师?
  17. 量化新手初识Brinson绩效分解模型
  18. C++常见问题总结_构造函数与析构函数
  19. canvas 线条渐变追逐_canvas之渐变
  20. 短信验证码安全常见逻辑漏洞

热门文章

  1. Pycharm的.py文件的导入
  2. Android应用小工具(窗口小部件)
  3. WingIDE 5的安装与破解方法
  4. windows下 Qt 静态编译
  5. Windows XP硬盘安装Ubuntu 11.10双系统全程图解
  6. python卸载模块的方法汇总_Python卸载模块的方法汇总
  7. python编程基础人民邮电出版社_Python编程基础与应用
  8. Ajax 请求超时与网络异常
  9. Redis的常用命令——hash的常用命令
  10. Mac 技术篇-设置Finder文件管理显示文件路径