参考文献:http://blog.csdn.net/zhaqiwen/article/details/7904515

近日在看项目中的框架代码时,发现了了一个奇特的语法:长度为0的数组例如

uint8_t buf[];

我从未见过这样的写法,所以在网上查了查资料,了解并记录下来.

在标准的C/C++中,长度为0的数组是不被允许的,它算是一个C/C++扩展,如果你的编译器支持这个扩展,你就可以使用它.

VS系列编译器不完全支持这个扩展,如果你这样定义,多半会在编译时出现这样的警告:warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组,当 UDT 包含大小为零的数组时,无法生成复制构造函数或副本赋值运算符

GUN编译器完全支持这个扩展,你可以合法的声明长度为0的数组,但这种声明的最典型的用法就是位于数组中的最后一项,为了方便内存缓冲区的管理,例如:

struct Line{
uint32_t length;
char contents[];
};

在结构体中,长度为0的数组不会占用存储空间 ,在上述例子中 sizeof(Line)=4

在申请内存空间时,缓冲区的空间可以和结构体的空间一起申请,一次操作就可以完成.例如

uint32_t length = ;
struct Line *pLine = (struct Line *)malloc(sizeof (struct Line) + length);
pLine->length = length;

上述代码就动态地为结构体申请了长度(length)为10byte的缓冲区,而且由于是同一次malloc操作,缓冲区与结构体的内存地址是连续的,而且可以按照数组下标访问缓冲区元素,例如

for(uint32_t i = ;i < pLine->length;++i)
{
pLine->contents[i] = i;
}

由于缓冲区与结构体的内存地址是连续的,在释放内存的时候,只需要一次free操作.

综上所述,比起在结构体中定义一个指针指向另一片缓冲区地址的做法,使用长度为0的数组有以下好处:

1->指针本身需要占用内存,而长度为0的数组不需要

2->长度为0的数组定义出的缓冲区可以和结构体处在同一片连续地址中,只要一次malloc操作和free操作.如果用指针,需要分别申请和释放结构体内存和指针指向的内存块,至少需要两次以上的内存操作.

测试代码:

编译器:  gcc version 4.8.1 (tdm-2)

#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
struct Line{
uint32_t length;
uint8_t contents[];
};
int32_t main()
{
uint32_t length = , i;
printf("sizeof(Line)=%d\n", sizeof(struct Line));
struct Line *pLine = (struct Line *)malloc(sizeof (struct Line) + length);
pLine->length = length;
for (i = ; i < pLine->length; ++i)
{
pLine->contents[i] = i;
}
for (i = ; i < pLine->length; ++i)
{
printf("i=%d,contents[i]=%d\n", i, pLine->contents[i]);
}
//free(pLine);
return ;
}

成功执行并打印结果:

sizeof(Line)=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
i=,contents[i]=
Press any key to continue . . .

在VS2013中编译运行上述代码,除了会报警告 " warning C4200 " 外,程序也可以正确运行.

C/C++ 中长度为0的数组的更多相关文章

  1. (转)C语言中长度为0的数组

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

  2. struct中长度为0的数组用途与原理

    前言 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNUC中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0]; 很多人可能觉得不可思议,长度为0的数组是没有什么意义的, ...

  3. Java中长度为0的数组与null的区别

    有如下两个变量定义,这两种定义有什么区别呢? 1. int[] zero = new int[0]; 2. int[] nil = null; zero是一个长度为0的数组,我们称之为“空数组”,空数 ...

  4. <转>浅析长度为0的数组

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

  5. c++ new长度为0的数组

    在程序中发现一下代码: int CHmcVideoMgt ::OnGetDiskRunningInfo( SOCKETPARAM *pSocketInfo ,Json:: Value Param ) ...

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

    在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在 ...

  7. C++ new 长度为0的数组

    在C++中可以new一个长度为0的数组,通过下面的语句: char* p = new char[0]; 指针p中保存一个非NULL的地址,但是你不能够对p指向的内存进行写入,因为p的内存长度为0, 该 ...

  8. 【C语言高级编程】你见过长度为0的数组吗?管你信不信,看就完了!

    一.什么是零长度数组 零长度数组就是长度为0的数组. ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的.在ANSI C 中定义一个数组的方法如下: 类 ...

  9. Oracle中长度为0字符串与null等价

    不试不知道,Oracle中,长度为0的字符串'' 居然与null等价! 众所周知,null代表空,什么都不存在,而一个字符串'',虽然长度为0,但毕竟已经是一个字符串,二者怎么能等价,混为一谈呢. 在 ...

随机推荐

  1. ArduinoYun的电源插座

    ArduinoYun的电源插座 Arduino Yun有两排插座,这些插座可以按类型分为三类:电源.数字IO和模拟输入.电源部分主要集中在如图1.7所示的部分本文选自Arduino Yun快速入门教程 ...

  2. sprint1的个人总结及《构建之法》8、9、10章读后感

    对sprint1的总结: 我们这次的sprint1做的挺差的,大家原来说好的分工都没有完成,也许是大家这段时间的大作业花了更多的时间,所以对这次团队任务的进度是拖慢了很多,但是团队已经认清了现阶段的问 ...

  3. HDU 2853 & 剩余系+KM模板

    题意: 给你一张二分图,给一个原匹配,求原匹配改动最少的边数使其边权和最大. SOL: 我觉得我的智商还是去搞搞文化课吧..这种题给我独立做我大概只能在暴力优化上下功夫.. 这题的处理方法让我想到了剩 ...

  4. HDU1853 & 蜜汁建图+KM模板

    题意: 给你一个N个点M条边的带权有向图,现在要你求这样一个值:该有向图中的所有顶点正好被1个或多个不相交的有向环覆盖.这个值就是 所有这些有向环的权值和. 要求该值越小越好. SOL: 本来还想ta ...

  5. javascript为元素绑定事件响应函数

    javascript中为元素设置响应时间有两种方法. (1):object.onclick=functionName; 这种方法不可以传递参数. (2):object.onclick=function ...

  6. eclipse 新建 java 文件时自动生成注释

    http://blog.csdn.net/kimsoft/article/details/5337910 Windows->Preference->Java->Code Style- ...

  7. 【BZOJ】1090: [SCOI2003]字符串折叠(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1090 随便yy一下.. 设f[i,j]表示i-j的最小长度 f[i, j]=min{j-i+1, f ...

  8. Linux_使用Linux之安装jdk 7

    工具/原料 jdk7源码安装压缩包 方法/步骤   卸载OpenJDK rpm -qa | grep java rpm -e --nodeps java-1.6.0-openjdk-1.6.0.0-1 ...

  9. [转] - Ubuntu 安装Eclipse

    昨天捣鼓一天,终于在Linux下成功安装Eclipse,这样,就能在Linux下像Windows的Visual Studio一样写程序了. 在网上搜索各种方法,但是没有一种方法是完整可行的,结合各种帖 ...

  10. php 配置正确的时间

    关于php时区时间错误问题 date 当前时间 时差 当地 本地date_default_timezone_set 之前有一个遗留问题,就是echo date("y-m-d h:i:s&qu ...