C语言解释器的实现--存储结构(一)
目录:
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;
C语言解释器的实现--存储结构(一)的更多相关文章
- C语言实现链表(链式存储结构)
链表(链式存储结构)及创建 链表,别名链式存储结构或单链表,用于存储逻辑关系为 "一对一" 的数据.与顺序表不同,链表不限制数据的物理存储状态,换句话说,使用链表存储的数据元素,其 ...
- 图的存储结构大赏------数据结构C语言(图)
图的存储结构大赏------数据结构C语言(图) 本次所讲的是常有的四种结构: 邻接矩阵 邻接表 十字链表 邻接多重表 邻接矩阵 概念 两个数组,一个表示顶点的信息,一个用来表示关联的关系. 如果是无 ...
- 队列的存储结构和常见操作(c 语言实现)
一.队列(queue) 队列和栈一样,在实际程序的算法设计和计算机一些其他分支里,都有很多重要的应用,比如计算机操作系统对进程 or 作业的优先级调度算法,对离散事件的模拟算法,还有计算机主机和外部设 ...
- C语言浮点数存储结构
float类型占四个字节,每个字节占8位,总共32位,其内存结构如下图: 31位为符号位:0表示正数,1表示负数 31~23位:共8位表示指数位,内存存储数据从0~2^8-1=255,由于指数可以是正 ...
- 图的存储结构与操作--C语言实现
图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...
- <编译原理 - 函数绘图语言解释器(1)词法分析器 - python>
<编译原理 - 函数绘图语言解释器(1)词法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 解释器分为三个实现块: 词法分析器: ...
- <编译原理 - 函数绘图语言解释器(2)语法分析器 - python>
<编译原理 - 函数绘图语言解释器(2)语法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 设计思路: 设计函数绘图语言的文法, ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- 智能合约语言 Solidity 教程系列6 - 结构体与映射
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本系列文章一部分是参考Solidity官方文档(当前最新版 ...
随机推荐
- 分布式版本号控制系统Git(二):github
前言 但凡是喜欢研究技术,或者听大牛们说起过的,都应该至少是听过github这个东西.详细就不介绍了.不了解的能够去了解了解,最基本的功能当然是代码托管啦,上面有各种各样的大牛写的项目. 另外这一章不 ...
- nodejs 打印机打印 pos打印
https://www.npmjs.com/package/chn-escpos 安装window vsbuild 编译工具 npm install --global --production win ...
- gulp在ionic中的使用
简介 Gulp是一个基于流的自动化构建器. 安装 npm config set registry http://registry.npm.taobao.org ---最好用国内源 npm instal ...
- python(9)- python基础知识刷题
1. 执行 Python 脚本的两种方式 交互方式:命令行 Windows操作系统下,快捷键cmd,输入“python”启动交互式python解释器. 文件方式:python文件 2. 简述位.字 ...
- C99_变长结构体实现
/************************************************************************* > File Name: C99_lengt ...
- AngularJs 常用
Angularjs开发一些经验总结:http://www.cnblogs.com/whitewolf/archive/2013/03/24/2979344.html 七步从AngularJS菜鸟到专家 ...
- MapReduce框架在Yarn上的具体解释
MapReduce任务解析 在YARN上一个MapReduce任务叫做一个Job. 一个Job的主程序在MapReduce框架上实现的应用名称叫MRAppMaster. MapReduce任务的Tim ...
- 并发回射服务器的最基本实现思路( fork )
前言 一个服务器,通常会在一段时间内接收到多个请求.如果非要等到处理完一个请求再去处理下一个,势必会造成大部分用户的不满( 尤其当有某个请求需要占用大量时间时 ).如何解决这个问题?让处理这些用户请求 ...
- 模式识别之ocr项目---(模板匹配&BP神经网络训练)
摘 要 在MATLAB环境下利用USB摄像头采集字符图像,读取一帧保存为图像,然后对读取保存的字符图像,灰度化,二值化,在此基础上做倾斜矫正,对矫正的图像进行滤波平滑处理,然后对字符区域进行提取分割出 ...
- UVA - 1045 The Great Wall Game(二分图最佳完美匹配)
题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...