"); //-->
前面在看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);
}
这段程序的运行结果如下图所示:
从上面的结果可以看出:
1、 长度为的数组并不占有内存空间,而指针方式需要占用内存空间。
2、对于长度为数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。
3、 对于长度为的数组的访问可采用数组方式进行。
原文地址:http://blog.csdn.net/zhaqiwen/article/details/7904515
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
三菱FX系列PLC教程 11 —— FX系列的工作方式
三菱FX系列PLC教程 10 —— FX系列的工作原理及编程器件(二)
高通推出第四代骁龙6移动平台,带来出色性能与增强的游戏体验
论AGI时代AI的本质
罗克韦尔自动化发布《可持续发展2024年度报告》
怎样才能编译出uclinux.rom?
LM4730/4731具有静音/待机模式的立体声音频功率放大器
MCX L系列:超低功耗MCU是如何实现的?
89C51 单片机IO 口模拟串行通信的实现方法
LM4730/4731的双电源供电音频功率放大电路
LM4730/4731的单电源供电音频功率放大电路
三菱FX系列PLC教程 8 —— FX系列的软件系统和编程语言
51系列单片机的uC_OS-II
恩智浦持续深化在华布局,开启中国战略新篇章!
静态图像编码软件jpeg2000(for vxworks)使用说明
51单片机的 中文拼音输入法 c源程序
含嵌入式Linux课程ARM 认证暨实战培训(北京)
LM4700/4701的辅助音频功率放大电路
热烈庆祝嵌入式商城开通
英飞凌成立新业务部门加强传感器和射频产品组合
首款基于i.MX MPU的FRDM开发板推出:工业物联网边缘计算开发理想之选!
三菱FX系列PLC教程 9 —— FX系列的工作原理及编程器件(一)
74hc595 串行输入,串、并行输出芯片 及其应用程序
意法半导体监事会拟在2025年度股东大会提名新监事人选
蔡崇信确认:阿里与苹果合作
三菱FX系列PLC教程 7 —— FX系列的扩展单元
LM4700/4701构成的电桥输出音频功率放大器电路
Analog Devices 的 DSP开发软件
650V耐压GaN HEMT新增小型与高散热TOLL封装
sdt2.51 debugger时的一个错误