(转)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 ) ...
随机推荐
- c 预处理的宏定义
概念 以“#”号开头的都是预处理命令 例如 #include <stdio.h>宏定义 宏定义无参数的宏名后不带参数# 表示这是一条预处理命令, define 为宏定义命令.“标识符”为所 ...
- 【WPF】WPF DataGrid List数据源 双向绑定通知机制之ObservableCollection使用以及MultiBinding 的应用
以下代码实现了DataGrid的简单绑定List数据源 重点要提一下的是,绑定List数据源,但是不能直接用List.比如下面的代码,使用List<GridItem>只能实现数据修改的绑定 ...
- Unity下Iso和Persp两种模式的区别
Iso模式 平行视野.在Iso模式下,不论物体距离摄像头远近都给人的感觉是一样大的. Persp模式 透视视野.在persp模式下,物体在scene界面上所呈现的画面是给人一种距离摄像头近的物体显示的 ...
- 贫血模型;DTO:数据传输对象(Data Transfer Object);AutoMapper ;Domain Model(领域模型);DDD(领域驱动设计)
====================== 我自己的理解 ========================== 一: DTO 我自己的理解,就是 比如你有一个类,跟数据库的table表结构一模一 ...
- TargetScan 数据库简介
TargetScan 是一个miRNA 靶基因预测的网站, 包括了 人, 小鼠,果蝇 , 线虫, 斑马鱼 共5个物种的miRNA 靶基因结果, 人 : TargetScanHuman 小鼠 :Targ ...
- js 创建多行字符串
function heredoc(fn) { ,-).join('\n') + '\n' } var tmpl = heredoc(function(){/* !!! 5 html include h ...
- opengl deferred shading
原文地址:http://www.verydemo.com/demo_c284_i6147.html 一.Deferred shading技术简介 Deferred shading是这样一种技术:将光照 ...
- Netbeans配置Java SE嵌入式平台(树莓派)
1.配置平台 来源:http://www.cnblogs.com/xiaobo-Linux/p/7955769.html 2. 选择远程 3. 填写信息 JRE 路径是树莓派上的路径:how? sud ...
- js sendBeacon
页面性能日志: DNS解析耗时 TCP链接耗时 SSL安全链接耗时 网络请求耗时 DOM解析耗时 资源加载耗时 首包时间 白屏时间 首次可交换时间 Dom Ready时间 页面完全加载时间. 如某些统 ...
- 安装配置和使用HBASE Cluster(基于发行版CDH5.0.2)——系列随笔
本系列文章只是记录了笔者本人在学习实验安装和使用基于CDH5.0.2的HBASE集群过程中的一些经验教训和心得,绝不是详细的安装过程,因本人不过一初学者,很多方面不甚了了,如果能让不幸读到的人有所得则 ...