结构体中最后一个成员为[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长度的数组成员作为自己的非标准扩展。

示例代码:

[cpp] view plaincopy
  1. #include <iostream>
  2. using namespace std;
  3. typedef struct _FlexibleArray
  4. {
  5. char ch;
  6. int arr[0];//int arr[];//int arr[1];
  7. }FlexibleArray;
  8. int main()
  9. {
  10. cout<<sizeof(FlexibleArray)<<endl;
  11. const int LENGTH = 10;
  12. FlexibleArray* flexibleArray = (FlexibleArray*)new char[sizeof(FlexibleArray) + LENGTH * sizeof(int)];
  13. for (int i = 0; i < LENGTH; i ++) {
  14. flexibleArray->arr[i] = i * i;
  15. }
  16. for (int i = 0; i < LENGTH; i ++) {
  17. cout<<flexibleArray->arr[i]<<endl;
  18. }
  19. delete [] flexibleArray;
  20. return 0;
  21. }

参考文献:

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

转自这个地方

C/C++ 学习笔记:结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法相关推荐

  1. Go语言学习笔记——结构体中使用tag标记

    文章目录 golang结构体中使用tag标记 简介 语法结构 快速入门 常见应用 应用json编码 应用xml编码 应用form表单绑定 gin框架form和数据绑定 golang结构体中使用tag标 ...

  2. C语言学习笔记---结构体中的字符数组和字符指针

      在结构体中可以使用字符数组来存储字符串,也可以使用字符指针来存储字符串.比如: struct str{char s1[5];char s2[5];};struct str str1= {" ...

  3. SV学习笔记—结构体及枚举类型及字符串

    目录 1.结构体 1.1 压缩结构体 1.2 非压缩结构体 1.3联合结构体 2.枚举类型 3.字符串 1.结构体 Verilog的最大缺陷之一是没有数据结构,SV中可以使用struct语句创建结构, ...

  4. 结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

    结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占 ...

  5. C语言学习笔记---结构体指针

      既然结构体是一种数据类型,那么除了使用变量本身来访问结构体之外,也可以使用指针来访问结构体.下面通过一个简单的例子来演示一下: struct Date{int year;int month;int ...

  6. C语言学习笔记---结构体数组初始化

      既然结构体是一种数据类型,那么它也可以定义为数组的形式.比如要描述一本书的信息,可以将书的名称,作者,价格这些信息用一个结构体来描述,在使用的过程中不可能只描述一本书,所以就需要使用一个结构体数组 ...

  7. C语言学习笔记---结构体的定义和初始化

      在C语言中结构体通常用来将不同类型的变量打包在一起,方便对对象的统一管理. 结构体定义   要使用结构体时,首先要进行结构体的声明.声明的形式如下: struct 结构体名{ 结构体所包含的变量} ...

  8. STM32学习笔记——结构体

    寄存器结构体定义 头文件 当我们完成了第一个试验后,或许会发现在头文件的部分,如果我们只用到一个端口,定义的量还尚可,但如果当我们有多个端口需要定义时,那我们就需要重复上面的所有定义再改去端口名,这样 ...

  9. golang学习笔记(结构体+json)

    结构体 结构体等价关系,只有==和!=关系,没有> < 关系,只有字段和属性完全相同,才等价,并且属于同一类型结构体,不同结构体不能比较,每一个不同的指针结构体的地址均不同 type Us ...

最新文章

  1. execute、executeQuery和executeUpdate之间的区别
  2. [网站搭建] 阿里云虚拟主机搭建及FTP文件上传
  3. 最常见的20种VC++编译错误信息
  4. Tableau研学小课堂(part7)--计算字段
  5. hdu 5813 Elegant Construction
  6. 计算机应用头部案例提交,基于头部位置的应用程序放置的制作方法
  7. Nginx使用HTTPS建立与上游服务器的网络通信
  8. andorid平台游戏内存修改器的开发思路
  9. 保研之路——北航网安学院直硕夏令营
  10. 基于SpringBoot实现简易的单点登录系统(提供gitee源码)
  11. 决策树分类——附数据下载
  12. android activity是什么呢
  13. 【HDU2019多校】E - Snowy Smile (最大字段和)
  14. 《虎胆龙威4》观后感
  15. IMPLEMENT_DYNAMIC
  16. 利用C++实现简单的文件加密
  17. win7用友u8安装教程_win7安装用友U8教程详解
  18. 【Python】Decision on buying cars COROLLA or LEVIN(数据分析技术实现过程之·2 data_analysis①)
  19. 《大道至简》第二章读后感--是懒人造就了方法
  20. 两分钟学会用ADC0804采集数据

热门文章

  1. 【Web技术】1002- 应式布局,你需要知道的一切
  2. 热血传奇技术的一些基础知识
  3. Codeforces Round #512 (Div. 2 E. Vasya and Good Sequences 异或问题
  4. laravel 隐藏 x-powered-by
  5. 组态王图素制作_组态王实例教程入门
  6. 来自日本的品质传承 工机控股发布新品牌HiKOKI战略
  7. JavaSE——网络编程
  8. 页面静止一定时间没有操作跳转页面
  9. gulp前端自动化构建工具:常用插件介绍及使用
  10. 华为手机升级回退_华为荣耀手机系统回退