C语言解释器的实现--存储结构(一)

简介:

目录:

     1. 内存池

     2. 栈

     3. Hash表

1.内存池
  在一些小的程序里,没什么必要添加内存管理模块在里面。但是对于比较复杂的代码,如果需要很多的内存操作,那么加入自己的内存管理是有必要的。至少有一些好处:能够加快内存的申请和释放;能够轻松的查找内存泄露问题;能够对整个软件的内存消耗做一个比较精确的统计;对以后的优化有很大的好处等等。所以,在我的解释器里,我加入了一个简单的内存管理模块,仿造了内存池的做法。
  主要思想是这样的:
  a.记录所有的申请的内存
  b.当释放内存时,记录下来以供下次申请使用
  c.申请内存时,可以直接使用前面释放过的内存
  为了达到以上的功能。我为申请内存的大小划分粒度,例如:我得粒度这么安排{16,32,64,128,...}那么申请17个字节的大小时候,我会申请32个字节的大小。这样子方便管理。并且为每个粒度创建一个可用内存的双向链表。申请内存时,就可直接从这些链表头中申请(即将一个节点从链表头移除,作为被申请的空间,并插入到在使用的链表中),内存的释放则是一个想法的过程。这些的存储结构如下所示:
  
  (图1.1 内存池的存储结构)
  
typedef struct _pool_block{
    int size;
    void * data;
    struct _pool_block * next;
    struct _pool_block * pre;
}pool_block_t;

typedef struct _pool{
    int num_all;
    int num_free;
    pool_block_t * list_all;
    pool_block_t * list_free[POOL_ATOM_NUM];
}pool_t;

int pool_atom_tab[POOL_ATOM_NUM] = {
    32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, -1
};

  说明:
  a.内存的申请会按照pool_atom_tab数组中的大小对齐,比如申请10byte,那么,我会申请32byte.
  b.为每个粒度保存一个双向链表,用于保存被释放的内存。如果要申请的内存超过8192,那么我直接调用系统的malloc,释放时,直接调用free.
  c.内存申请过程:到相应的粒度链表(list_free)中查看是否有可用内存,如果有,直接将它从该list_free链表中移动到list_all链表。
  d.内存释放过程:要释放的内存必定保存在list_all中,根据它的大小,把它移动到相应的list_free链表。
  e.pool_block_t结构被放置在申请内存的前面,则在释放时,直接根据Buffer指针就可得到pool_block_t的位置,从而得到next和pre,快速的在链表中移动。

2.栈
  栈在解释器中用到的地方很多,不管是表达式的解析,还是代码块的解析,类型的解析,等等都用到了栈。所以不实现它是不可能的事,不过在数据结构中他是最简单的了,无非就是申请一个空间,按一个一个的节点保存进去,按一个一个的节点取出来。没什么技巧在里面,只是这个我让栈的大小空间是自动增长和减小的,这么做的目的是:栈的空间仅仅限制于内存的大小。但是,这么做得缺点是,当栈的空间大小自动变化时,栈内的数据要被复制一遍,这务必会影响效率。但没有办法,暂时之能这样了。唯一的办法是在时间和空间上做一个选择。
  栈的存储结构如下:
  
  (图1.2 栈的存储结构)
  
typedef struct _stack{
    int item_len;
    int item_num;
    int stack_size;
    char *p;
}stack_t;
  
  说明:
  item_len:   保存每个节点的长度
  item_num:   栈中节点的个数
  stack_size: 栈中可保存的节点个数
  p:          指向栈空间
  a.当节点的个数item_num大于stack_size,那么必须重新申请空间,将原来的数据拷贝到新的空间。
  b.当节点的个数减小到一定的数量时,可以重新申请小的数据空间,释放原来大的空间。


3.hash表
  hash由于其快速的查找能力而著称,但是它太浪费内存了,所以用得的比较少,仅仅是在函数的调用时被使用。因为函数的调用是频繁的,如果从头查找函数,那将浪费很多的时间。这里引入hash也是必要的。
  
#define HH_TAB_SIZE 128

typedef struct _hh_node{
    unsigned int hash, klen, dlen;
    void * key;
    void * data;
    struct _hh_node *next;
}hh_node_t;

typedef struct _hh_head{
    unsigned int node_num;
    hh_node_t *  node_list;
}hh_head_t;

typedef struct _hh_hash{
    hh_opts_t opts;
    hh_head_t tabs[HH_TAB_SIZE];
}hh_hash_t;

typedef struct _hh_opts{
    int (*cmp_key)(void *key1, void *key2);
    unsigned int (*get_hash)(void *key);
    void * (*new_key)(int);
    void * (*new_data)(int);
    void (*del_key)(void *key);
    void (*del_data)(void *data);
}hh_opts_t;

目录
相关文章
|
2月前
|
网络协议 编译器 Linux
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
108 0
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
477 0
|
3月前
|
存储 编译器 C语言
C语言存储类详解
在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
170 82
|
1月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
94 16
|
2月前
|
存储 C语言
C语言中的浮点数存储:深入探讨
C语言中的浮点数存储:深入探讨
|
2月前
|
编译器 C语言 Python
C语言结构
C语言结构
22 0
|
2月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
3月前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
485 8
|
3月前
|
存储 编译器 程序员
C语言程序的基本结构
C语言程序的基本结构包括:1)预处理指令,如 `#include` 和 `#define`;2)主函数 `main()`,程序从这里开始执行;3)函数声明与定义,执行特定任务的代码块;4)变量声明与初始化,用于存储数据;5)语句和表达式,构成程序基本执行单位;6)注释,解释代码功能。示例代码展示了这些组成部分的应用。
139 10
|
3月前
|
C语言
C语言程序设计核心详解 第四章&&第五章 选择结构程序设计&&循环结构程序设计
本章节介绍了C语言中的选择结构,包括关系表达式、逻辑表达式及其运算符的优先级,并通过示例详细解释了 `if` 语句的不同形式和 `switch` 语句的使用方法。此外,还概述了循环结构,包括 `while`、`do-while` 和 `for` 循环,并解释了 `break` 和 `continue` 控制语句的功能。最后,提供了两道例题以加深理解。
107 7