(转)C语言中长度为0的数组
前面在看Xen的源码时,遇到了一段代码,如下所示:

注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0 的数组?长度为的数组到底怎么使用?……这篇文章主要针对该问题进行简单的讲解。废话不多说了,现在就开始。
长度为的数组在标准c和c++中是不允许的,如果使用长度为的数组,编译时会产生错误,提示数组长度不能为。但在GNUc中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理。如果你将上面的长度为的数组换为指针,那么在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。
对于长度为的数组,在gcc手册中,有如下一段代码片段:
struct line {
int length;
char contents[];
};
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[];
}__attribute((packed)); struct test3 {
int a;
int b[];
}__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 = ;
var1->b = (int *) malloc(sizeof(int));
*var1->b = ;
printf("\nvar1->a=%d,*(var1->b)=%d\n", var1->a, *var1->b); var2 = (struct test2*) malloc(sizeof(struct test2) + sizeof(int) * LENGTH);
var2->a = ;
printf("\nvar2->a=%d\n", var2->a);
for (i = ; 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 = ;
(var3->b)[] = ;
printf("var3->a=%d,(var3->b)[0]=%d\n", var3->a, (var3->b)[]); free(var1->b);
free(var1);
free(var2);
free(var3); }
这段程序的运行结果如下图所示:

从上面的结果可以看出:
1、 长度为的数组并不占有内存空间,而指针方式需要占用内存空间。
2、对于长度为数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。
3、 对于长度为的数组的访问可采用数组方式进行。
原文地址:http://blog.csdn.net/zhaqiwen/article/details/7904515
(转)C语言中长度为0的数组的更多相关文章
- C/C++ 中长度为0的数组
参考文献:http://blog.csdn.net/zhaqiwen/article/details/7904515 近日在看项目中的框架代码时,发现了了一个奇特的语法:长度为0的数组例如 uint8 ...
- struct中长度为0的数组用途与原理
前言 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNUC中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0]; 很多人可能觉得不可思议,长度为0的数组是没有什么意义的, ...
- Java中长度为0的数组与null的区别
有如下两个变量定义,这两种定义有什么区别呢? 1. int[] zero = new int[0]; 2. int[] nil = null; zero是一个长度为0的数组,我们称之为“空数组”,空数 ...
- 【C语言高级编程】你见过长度为0的数组吗?管你信不信,看就完了!
一.什么是零长度数组 零长度数组就是长度为0的数组. ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的.在ANSI C 中定义一个数组的方法如下: 类 ...
- GNU C的定义长度为0的数组
在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在 ...
- C语言中指针和多维数组
指针和多维数组 数组名是特殊的指针 数组是一个特殊的指针,多维数组也是更为复杂的数组,它们的关系是什么样的呢? 我们通过一个简单的例子来比较形象的了解指针和多维数组: int a[2][3]; 这是一 ...
- <转>浅析长度为0的数组
前面在看Xen的源码时,遇到了一段代码,如下所示: 注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0 的数组?长度为的数组到底怎么使用?……这篇文章主要针对该 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- c++ new长度为0的数组
在程序中发现一下代码: int CHmcVideoMgt ::OnGetDiskRunningInfo( SOCKETPARAM *pSocketInfo ,Json:: Value Param ) ...
随机推荐
- Tornado + Celery + RabbitMQ
声明:代码是从项目中截取的, 为进行测试 使用Celery任务队列,Celery 只是一个任务队列,需要一个broker媒介,将耗时的任务传递给Celery任务队列执行,执行完毕将结果通过broker ...
- Batch normalization:accelerating deep network training by reducing internal covariate shift的笔记
说实话,这篇paper看了很久,,到现在对里面的一些东西还不是很好的理解. 下面是我的理解,当同行看到的话,留言交流交流啊!!!!! 这篇文章的中心点:围绕着如何降低 internal covari ...
- 理解Java动态代理(1)—找我还钱?我出钱要你的命
代理模式是最常用的一个设计模式之一,理解起来也是很简单,一张图足以说明了,LZ就不废话了. 至于代理模式能干嘛也不是LZ今天想说的,今天主要想简单介绍下JAVA里面的动态代理.“动”当然是相对“静”来 ...
- 生成基于Maven的项目文档站点
在Maven中,可以使用“mvn site”,为您的项目信息生成文档站点. mvn site 生成的网站是在项目的“target/site”文件夹中. mvn site 示例 请参见通过“mvn si ...
- k8s sidecar, Ambassador, Adapter containers
When you start thinking in terms of Pods, there are naturally some general patterns of modular appli ...
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...
- nodejs npm 使用淘宝 NPM 镜像
使用淘宝 NPM 镜像 大家都知道国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像. 淘宝 NPM 镜像是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读), ...
- [转]Phantomjs实现获取网页快照并生成缩略图
Shell脚本实现获取网页快照并生成缩略图 这篇文章主要介绍了Shell脚本实现获取网页快照并生成缩略图,本文获取网页快照使用phantomjs.生成缩略图使用ImageMagick,需要的朋友可以参 ...
- 【python-proxy by sockets5】pysocks
pip install pysocks https://stackoverflow.com/questions/2317849/how-can-i-use-a-socks-4-5-proxy-with ...
- 2015-10-07:几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右
最近发现(2015-10-07)几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右