参考文献: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. js:语言精髓笔记1--标识符与基本类型

    标识符: 命名: 语法以及类型----语法关键字                                           //逻辑 值(的存储位置)----变量和常量           ...

  2. BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)

    挺直白的构图..最小费用最大流的定义. #include<cstdio> #include<cstring> #include<queue> #include< ...

  3. 错误:不存在类型或命名空间名称 "Control”

    编译时出现如下错误: 命名空间中不存在类型或命名空间名称 "Control"(是否缺少程序集引用?).     在引用中添加UIAutomationProvider后解决.

  4. CodeForces Round 195 Div2

    A. Vasily the Bear and Triangletime limit per test1 secondmemory limit per test256 megabytesinputsta ...

  5. MatLab GUI Load .mat File 导入mat文件

    在MatLab中,我们用GUI时,有时候需要导入mat格式的图片,但是在GUI中调用load和在命令行里调用load不一样,在命令行里调用load('im.mat'),加载进去是uint8的矩阵,但是 ...

  6. hdu Line belt

    这道题是一道3分搜索的题.其实这种题很多时候都出现在高中的解析几何上,思路很简单,从图中可以看到,肯定在AB线段和CD线段上各存在一点x和y使得所花时间最少 因为AB和CD上的时间与x和y点的坐标都存 ...

  7. 序号自增key的使用

    由于在模板中,需要输出序号,但是从数据库中提取的话,保证不了序号的连续性. 在模板中我就使用foreach循环,查手册看到foreach的使用 但是我还是没从手册中学会key的使用.尝试使用 结果,如 ...

  8. sql中写标量函数生成大写拼音首字母

    USE [StockManageSystemV2] GO /****** Object: UserDefinedFunction [dbo].[PinYin] Script Date: 2016-08 ...

  9. kail-linux 安全之旅

    一些学习网站 http://xiao106347.blog.163.com/blog/static/2159920782013111995945233/ http://xiao106347.blog. ...

  10. sql 语句大小写的问题

    关键字不区分大小写 例如 select ,from, 大小写均可 标识符区分大小写 例如 表名,列名 标识符如果不加双引号,默认是按大写执行 标识符如果加双引号,则是按原始大小写执行 但是,当表名加上 ...