一个C语言内存管理模块的实现
C 内存管理模块的编写
C语言手动管理内存很困难,有时候很难发现内存泄漏,这两天看了一下<自制编程语言>里面有写了一个简单的内存管理模块,发现挺精巧,可以有效检测内存泄漏
原理很简单,就是把C的malloc函数分配的内存用一个链表记录起来,最后查看这个链表是否还有节点就可以判断是否有内存泄漏了
首先我们先看一下这个链表的数据结构
//标记数组的大小
#define MARK_SIZE 4
typedef struct Mem_Header Mem_Header;
struct Mem_Header
{
int size;//后面内存分配的大小
Mem_Header *next;//下一个节点的指针
Mem_Header *prev;//上一个节点的指针
char *filename;//文件名指针
int line;//在第几行
unsigned char mark[MARK_SIZE];//标记数组,这个数据用来表示这块内存是否被破坏了
}
这个mark数组我们将用 0xcd填充,如果这个数组被动过了就说明这块内存被破坏了
我们每次malloc一块内存的时候,这个结构体就会被添加到这块内存的头部
就像这样:
void *p = malloc(size);
Mem_Header *header = (Mem_Header *)p;
//然后设置header信息
/*省略一些赋值过程*/
return (char*)header+sizeof(Mem_Header);
这样外部拿到的指针就可以随便用了,回收的时候还可以重新推出头部指针的信息,然后从链表中删除这个节点
为了防止后面溢出,可以在后面内存也加上 mark数组 这样我们每次分配的内存大小是 sizeof(Mem_Header) + size + MARK_SIZE
其中size是需要分配的大小,MARK_SIZE是在后面加的标记数组
我们用malloc初始化的时候经常碰到0,我们把这块内存填充0xcc(没意义的值别的其实也行),更容易发现错误
memset(p, 0xcc, willAlloc);
我们先来看第一个函数:
//size 需要分配的大小
//filename 文件名
//line 行好
void *Mem_alloc(Mem_Controller *controller, size_t size, char *filename, int line)
{
int willAlloc = size + MEM_HEADER_SIZE + MARK_SIZE;//实际分配大小
void *p = malloc(willAlloc);
if (!p)
controller->handle(controller, filename, line, "malloc null");
//填充数组
memset(p, 0xcc, willAlloc);
//设置头部一些信息
Mem_setHeader(p, size, filename, line);
//设置tail的信息
Mem_setTail(p, size);
//把这个节点添加到链表中
Mem_addChain(controller, (Mem_Header *)p);
return (char *)p + MEM_HEADER_SIZE;
}
这个函数就是分配一个内存,controller是控制器,实际上就是负责打印和保存头指针的
filename和line就是分配空间时候的文件和行号,可以用宏定义解决可以百度一下这两个宏__LINE__,__FILE__
内存释放:从链表中删除这个节点
void Mem_free(Mem_Controller *controller, void *p, char *filename, int line)
{
if (!p)
return;
//头信息
Mem_Header *header = (char *)p - MEM_HEADER_SIZE;
//check header and tail
//检查是不是mark数组损坏了
Mem_check(controller, header, filename, line);
//移除节点
Mem_rmChain(controller, header);
free(header);
}
打印所有链表中的节点
void Mem_dumps(Mem_Controller *controller)
{
Mem_Header *pos = controller->memHeader;
FILE *fp = stderr;
int counter = 0;
for (pos = controller->memHeader; pos; pos = pos->next)
{
Mem_check(controller, pos, pos->filename, pos->line);
fprintf(fp, "[%04d]%p********************\n", counter,
(char *)pos + MEM_HEADER_SIZE);
fprintf(fp, "%s line %d size..%d\n",
pos->filename, pos->line, pos->size);
counter++;
}
}
为了方便我们使用,我们可以设置几个宏定义
typedef struct Mem_Controller Mem_Controller;
extern Mem_Controller *pcontrol;
void *Mem_alloc(Mem_Controller *controller, size_t size, char *filename, int line);
void Mem_free(Mem_Controller *controller, void *p, char *filename, int line);
void Mem_dumps(Mem_Controller *controller);
#define current_mem_controller pcontrol
#define Mem_alloc_func(size) Mem_alloc(current_mem_controller, size, __FILE__, __LINE__)
#define Mem_free_func(p) Mem_free(current_mem_controller, p, __FILE__, __LINE__)
#define Mem_dump_func() Mem_dumps(current_mem_controller)
那个extern全局变量是别的文件定义的指针,__FILE__
会自动替换文件名,这样我们就可以看到是哪里的内存没有被释放
使用的时候也简单了很多直接用宏定义就可以了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MEM.h"
void fill_buffer(unsigned char *buf, int size)
{
int i;
for (i = 0; i < size; i++)
{
buf[i] = i;
}
}
void mem_print(unsigned char *p, int size)
{
for (int i = 0; i < size; i++)
{
fprintf(stderr, "%02x", p[i]);
}
fprintf(stderr, "\n");
}
int main()
{
void *p = Mem_alloc_func(10);
mem_print(p, 10);
void *p2 = Mem_alloc_func(10);
mem_print(p2, 10);
void *p3 = Mem_alloc_func(10);
mem_print(p3, 10);
Mem_dump_func();
fprintf(stderr, "try to clear\n");
Mem_free_func(p2);
Mem_free_func(p);
Mem_free_func(p3);
Mem_dump_func();
fprintf(stderr, "then to malloc\n");
p = Mem_alloc_func(10);
fill_buffer(p, 10);
p = Mem_realloc_func(p, 20);
mem_print(p, 24);
Mem_dump_func();
return 0;
}
我们可以看到泄漏的大小和行号
原版的代码的联合体是用来内存对齐的加快访问速度
一个C语言内存管理模块的实现的更多相关文章
- Go语言内存管理(一)内存分配
Go语言内存管理(一)内存分配 golang作为一种"高级语言",也提供了自己的内存管理机制.这样一方面可以简化编码的流程,降低因内存使用导致出现问题的频率(C语言使用者尤其是初学 ...
- C语言 内存管理(转)
转自 https://blog.csdn.net/u011616739/article/details/61621815 C语言 内存管理 1.内存分区 C源代码进过预处理.编译.汇编和链接4步生成 ...
- 深入理解Linux C语言内存管理
问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...
- rt-thread中动态内存分配之小内存管理模块方法的一点理解
@2019-01-18 [小记] rt-thread中动态内存分配之小内存管理模块方法的一点理解 > 内存初始化后的布局示意 lfree指向内存空闲区首地址 /** * @ingroup Sys ...
- C语言内存管理(转)
伟大的Bill Gates 曾经失言: 640K ought to be enough for everybody — Bill Gates 1981 程序员们经常编写内存管理程序,往往提心吊胆.如果 ...
- iOS学习08之C语言内存管理
本次主要学习和理解C语言中的内存管理 1.存储区划分 按照地址从高到低的顺序:栈区,堆区,静态区,常量区,代码区 1> 栈区:局部变量的存储区域 局部变量基本都在函数.循环.分支中定义 栈区的内 ...
- 深入理解C语言内存管理
之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...
- Objective-C语言内存管理
• Objective-C为每个对象提供一个内部计数器,这个计数器跟踪对象的引用次数.所有类都继承自 NSObject 的对象retain和release方法. 如果使用了new.alloc或copy ...
- 黑马程序员——OC语言 内存管理
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)计数器 每个对象内部都保存了一个与之相关联的整数,称为引用计数器,当 ...
随机推荐
- 《SQL Server 2008从入门到精通》--20180703
SELECT操作多表数据 关于连接的问题,在<SQL必知必会>学习笔记中已经讲到过,但是没有掌握完全,所以再学一下. JOIN连接 首先我们先来看一下最简单的连接.Products表和Ve ...
- 安装Window Server 2008的些配置
上次安装window server2008,由于server2008需要设置很多东西,不然用起来很不爽,就说IE吧,每次随便打开一个网页都要弹出n多窗口出来叫你添加到信任域里面!太烦人了![下面有解决 ...
- 有序字典(OrderedDict)、默认字典(defaultdict)内置函数
http://www.cnblogs.com/wupeiqi/articles/5115190.html import collections do = collections.OrderedDict ...
- Loadrunner11代理录制&各个常见功能介绍
1.代理录制: Lr代理工具:C:\Program Files (x86)\HP\LoadRunner\bin\wplus_init_wsock.exe 1) 设置代理 配置代理信息: 2)设置浏览器 ...
- 北美Developer生存发展攻略
http://www.followmedoit.com/bbs/forum.php?mod=viewthread&tid=49&extra=page%3D1 在北美,做PM不易,而做D ...
- Linux 系统的网络基础_【all】
网络基础 1.网线:568B: 白橙 橙色 白绿 蓝色 白蓝 绿色 白棕 棕色 2.交换机:电信号转发的网络设备,它可以为接入交换机的任2个网络节点设备提供电信号通信 3.路由器:连接局域网,广域网的 ...
- 深入浅出SharePoint2013——安装SharePoint2013
在这个页面的底部可以通过相应链接下载Sharepoint Server安装文件 https://technet.microsoft.com/en-us/library/cc262788.aspx
- HBase Master高可用(HA)
HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行. 所以这里要配置HBase高可用的话,只需要 ...
- Java基础知识强化之集合框架笔记79:HashMap的实现原理
1. HashMap的实现原理之 HashMap数据结构: HashMap是对数据结构中哈希表(Hash Table)的实现, Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Val ...
- 第一部分 OpenStack及其构成简介
一.云计算 云计算是一种计算模型,它将诸如运算能力.存储.网络和软件等资源抽象成为服务,以便让用户通过互联网远程享用,付费的形式也如同传统公共服务设施一样.因需而定.提供方便.动态改变和无限的虚拟 ...