结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势:(1)、不需要初始化,数组名直接就是所在的偏移;(2)、不占任何空间,指针需要占用int长度空间,空数组不占任何空间。“这个数组不占用任何内存”,意味着这样的结构节省空间;“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用。
这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(structXXX) + buff_len); 直接就把buffer的结构体和缓冲区一块分配了。用起来也非常方便,因为现在空数组其实变成了buff_len长度的数组了。这样的好处是:(1)、一次分配解决问题,省了不少麻烦。为了防止内存泄露,如果是分两次分配(结构体和缓冲区),那么要是第二次malloc失败了,必须回滚释放第一个分配的结构体。这样带来了编码麻烦。其次,分配了第二个缓冲区以后,如果结构里面用的是指针,还要为这个指针赋值。同样,在free这个buffer的时候,用指针也要两次free。如果用空数组,所有问题一次解决。(2)、小内存的管理是非常困难的,如果用指针,这个buffer的struct部分就是小内存了,在系统内存在多了势必严重影响内存管理的性能。要是用空数组把struct和实际数据缓冲区一次分配大块问题,就没有这个问题。如此看来,用空数组既简化编码,又解决了小内存碎片问题提高了性能。
结构体最后使用0或1长度数组的原因:主要是为了方便的管理内存缓冲区(其实就是分配一段连续的内存,减少内存的碎片化),如果直接使用指针而不使用数组,那么,在分配内存缓冲区时,就必须分配结构体一次,然后再分配结构体内的指针一次,(而此时分配的内存已经与结构体的内存不连续了,所有要分别管理即申请和释放)而如果使用数组,那么只需要一次就可以全部分配出来,反过来,释放时也是一样,使用数组,一次释放。使用指针,得先释放结构体内的指针,再释放结构体,还不能颠倒顺序。
结构体中最后一个成员为[1]长度数组的用法:与长度为[0]数组的用法相同,改写为[1]是出于可移植性的考虑。有些编译器不支持[0]数组,可将其改成[]或[1].
不完整类型(incomplete type):它缺乏足够的信息例如长度去描述一个完整的对象。(1)、前向声明就是一种常用的不完整类型, class base; struct test; base和test只给出了声明,没有给出定义。不完整类型必须通过某种方式补充完整,才能使用它们进行实例化,否则只能用于定义指针或引用,否则只能用于指针或引用,因为此时实例化的是指针或引用本身,不是base或test对象。(2)、一个未知长度的数组也属于不完整类型:extern
int a[]; extern不能去掉,因为数组的长度未知,不能作为定义出现。不完整类型的数组可以通过几种方式补充完整才能使用,大括号形式的初始化就是其中一种方式:int a[] = {10, 20};
柔性数组成员(flexible array member):也叫收缩性数组成员,这种代码结构产生于对动态结构体的需求。C99使用不完整类型实现柔性数组成员,在C99中,结构中的最后一个元素允许是未知大小的数组,这就叫柔性数组成员。但结构中的柔性数组成员前面必须至少一个其它成员。柔性数组成员允许结构中包含一个大小可变的数组。柔性数组成员只作为一个符号地址存在,而且必须是结构体的最后一个成员,sizefo返回的这种结构大小不包括柔性数组的内存。柔性数组成员不仅可以用于字符数组,还可以是元素为其它类型的数组。包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
C/C++标准规定不能定义长度为0的数组,因此,有些编译器就把0长度的数组成员作为自己的非标准扩展。
示例代码:
#include <iostream>
using namespace std;
typedef struct _FlexibleArray
{
char ch;
int arr[0];//int arr[];//int arr[1];
}FlexibleArray;
int main()
{
cout<<sizeof(FlexibleArray)<<endl;
const int LENGTH = 10;
FlexibleArray* flexibleArray = (FlexibleArray*)new char[sizeof(FlexibleArray) + LENGTH * sizeof(int)];
for (int i = 0; i < LENGTH; i ++) {
flexibleArray->arr[i] = i * i;
}
for (int i = 0; i < LENGTH; i ++) {
cout<<flexibleArray->arr[i]<<endl;
}
delete [] flexibleArray;
return 0;
}
参考文献:
1、
http://blog.chinaunix.net/uid-26750459-id-3191136.html
2、
http://blog.csdn.net/ce123_zhouwei/article/details/8973073
3、http://blog.csdn.net/code_crash/article/details/4854939
分享到:
相关推荐
柔性数组成员允许结构体的最后一个元素是一个长度为0的数组,这样做可以灵活地根据需要分配结构体后面的内存空间。 最后,文档提到将会有第二季的内容提供,这表明了结构体系列的深入讲解将陆续推出,为读者提供更...
C语言中柔性数组是指在结构体中定义一个数组,但是不指定数组的大小,而是根据实际需要动态分配内存空间的数组。这是一种常用的技术,特别是在网络通信和数据存储等领域。 首先,让我们来了解一下为什么需要使用...
柔性数组在结构体中的使用要求结构体至少有一个其他成员,然后在末尾定义一个未指定大小的数组。在内存分配时,需要使用`malloc`等动态分配函数为整个结构体以及柔性数组预留足够的空间。例如,如果要创建一个结构体...
此外,文件信息中也提到了一种柔性数组的使用,这可能是指在C语言实现中使用了柔性数组成员(flexible array member),这是C99标准引入的一种特性,允许结构体在最后一个元素是一个不指定大小的数组。这种技术在...
在编程领域,柔性数组(柔性数组成员)是一种C99标准引入的数据结构,它允许在结构体末尾添加一个长度可变的数组。这个概念出现在文件列表中,可能表明A2L文件合成工具在处理某些特定数据时具有一定的灵活性,例如在...
柔性数组是C99标准引入的一种数据结构,它允许在结构体的最后定义一个不确定长度的数组。这种特性基于动态内存分配,可以在运行时确定数组大小,为动态内存管理提供了更多的灵活性。 总结起来,动态内存管理技术是...
此类声明利用了结构体中的“柔性数组成员”来创建可变大小的结构体。这种做法是C99标准的一部分,但在某些编译器上可能不可用。 **2.7 是否有自动比较结构的方法?** 没有内置的方法,但可以手动编写函数逐个比较...
14. **C99和C11新特性**:例如柔性数组成员、匿名结构体和联合体、变量长度数组、内联函数等。 这个系列的第17集可能深入探讨了以上某个或多个主题,通过具体的实例或项目展示了C语言的强大功能。学习者可以通过这...
13. **C99和C11标准**:C语言的最新标准引入了新的特性,如柔性数组成员、匿名结构体和联合体、变量长度数组等。 通过深入学习和实践这些知识点,不仅可以帮助应届毕业生巩固理论基础,还能提升他们的编程技巧,为...
这本电子书对于任何想要深入理解和掌握C语言的人来说,都是一个不可或缺的学习资源。以下是该手册中可能包含的一些关键知识点: 1. **C语言基础**:书中可能会介绍C语言的基本语法,如变量、数据类型、运算符、控制...
- **柔性数组**:允许在结构体末尾定义一个未知长度的数组。 - **struct与class的区别**:在C++中,`struct`默认成员权限为public,而`class`默认为private。 **1.16 union关键字** - **大小端模式对union类型数据...