当前位置: 首页 > news >正文

关于柔性数组

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. 写在前面

    

前一段在看百度阿拉丁底层存储的时候,看到这样一段代码:

struct dlist_t
{
    dlist_t *next;
    u_int key;
    int size[0];
};

      印象中int size[0]这种在C/C++是不允许的,但是在结构中确实可以使用的(C99标准)。经过查看资料,知道这种可变数组被称为柔性数组。

2. 用法说明

    C99的标准形式如下

struct sample
{
       int a;
       double b;
       char c[]; //或者 char c[0]
};

      在结构体的最后,可以加入一个长度为0的数组c,这个数组c就是所谓的柔性数组。c只是一个偏移,通过动态申请c的大小可以达到动态结构的效果。

3. 例子

#include<cstring>
#include<iostream>
using namespace std;

#define uint32 unsigned int


typedef struct _normal_array_t
{
    char a;
    uint32 b;
    int *c;
}__attribute ((packed)) normal_array_t;

typedef struct _dynamic_array_t
{
    char a;
    uint32 b;
    int c[]; 
}__attribute ((packed)) dynamic_array_t;

int main()
{
    normal_array_t* n1 = (normal_array_t*)malloc(sizeof(normal_array_t) );
    cout << "n1: before malloc size is " << sizeof(*n1) << endl;
    n1->c = (int*) malloc(100);
    n1->c[50] =  100;
    cout << "n1: after malloc c, n1->c[50] is " << n1->c[50] << endl;
    cout << "n1: after malloc c, size is " << sizeof(*n1) << endl;
    free(n1->c);
    free(n1);

    dynamic_array_t* d1 = (dynamic_array_t*)malloc(sizeof(dynamic_array_t) + 100 * sizeof(int) );
    cout << "d1: size is " << sizeof(*d1) << endl;
    d1->c[50] = 200;
    cout << "d1: d1->c[50] is " << d1->c[50] << endl;
    free(d1);
}

   结果如下:

liujun@cq01-rdqa-dev012.cq01:~/test$ ./dynamic 
n1: before malloc size is 13
n1: after malloc c, n1->c[50] is 100
n1: after malloc c, size is 13
d1: size is 5
d1: d1->c[50] is 200

      如上图,我们如果想在struct里面声明一个动态的数组,可以有2种方式(里面的__attribute ((packed)) 是禁止编译器做字节对齐,效果明显).

      第一种如下所示,这种方法可以先申请normal_array_t自身,然后在申请normal_array_t->c,然后通过normal_array_t->c[index]来访问动态数组,使用之后,需要先free(normal_array_t->c),然后再free(normal_array_t);

      我的机器是64位,所以指针为8个字节,进而normal_array_t大小为13.

typedef struct _normal_array_t
{
    char a;
    uint32 b;
    int *c;
}__attribute ((packed)) normal_array_t;

     第二种方法如下所示,这种方法一次性申请normal_array_t加上需要动态数组的大小来申请一整块内存,然后通过dynamic_array_t->c[index]来访问动态数组,使用之后,需要先free(dynamic_array_t)就可以释放整个内存。

     可以看到dynamic_array_t->c仅仅是一个符号,dynamic_array_t的大小为5(char1, uint32 4)。

typedef struct _normal_array_t
{
    char a;
    uint32 b;
    int *c;
}__attribute ((packed)) normal_array_t;

4. 小结

     可以看到使用柔性数组可以大大简化内容的管理,只需要一次申请,然后通过数组的指针偏移就可以直接获得相应的数据缓冲区,非常简单,释放的时候也仅仅只需要一次释放。

转载于:https://my.oschina.net/jungleliu0923/blog/192956

相关文章:

  • 【Vegas原创】sendkeys实例
  • 【原创】PostgreSQL 实现MySQL insert ignore 语法。
  • 闲话网名(一)
  • 与后台的一些事情
  • XAML开发入门之创建XAML应用程序
  • 巧妙运用二进制验证权限
  • 网站部署成功...
  • 将SCOM2007代理升级到 System Center 2012 SP1
  • 一道有意思的问题
  • Ubuntu系统连接Android真机测试
  • 台湾校长高震东的演讲!
  • Node.js连接postgres
  • HFSoft.Data 2.0的Nunit测试用例
  • squid代理配置与应用
  • MDX函数使用介绍(四):字符串函数元组函数
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【翻译】babel对TC39装饰器草案的实现
  • 10个确保微服务与容器安全的最佳实践
  • Django 博客开发教程 16 - 统计文章阅读量
  • DOM的那些事
  • js 实现textarea输入字数提示
  • JSONP原理
  • Laravel核心解读--Facades
  • leetcode46 Permutation 排列组合
  • leetcode98. Validate Binary Search Tree
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Python十分钟制作属于你自己的个性logo
  • SQL 难点解决:记录的引用
  • Sublime text 3 3103 注册码
  • Swift 中的尾递归和蹦床
  • webpack4 一点通
  • 从PHP迁移至Golang - 基础篇
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 动态魔术使用DBMS_SQL
  • 基于 Babel 的 npm 包最小化设置
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 我从编程教室毕业
  • 我建了一个叫Hello World的项目
  • 小试R空间处理新库sf
  • 学习ES6 变量的解构赋值
  • 一起参Ember.js讨论、问答社区。
  • 阿里云ACE认证之理解CDN技术
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 说说我为什么看好Spring Cloud Alibaba
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ![CDATA[ ]] 是什么东东
  • ###C语言程序设计-----C语言学习(3)#
  • $forceUpdate()函数
  • $NOIp2018$劝退记
  • (09)Hive——CTE 公共表达式
  • (汇总)os模块以及shutil模块对文件的操作
  • (简单) HDU 2612 Find a way,BFS。
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (万字长文)Spring的核心知识尽揽其中
  • (译)2019年前端性能优化清单 — 下篇