一、前言
在用C语言开发产品时,由于C语言中的指针操作的灵活性,因此在使用指针时也需要特别小心,稍微不严谨就会导致内存问题,如内存未初始化,内存泄露,内存重复释放等。
但是在实际开发中,使用指针是不可避免的,那么出现内存问题也是不可避免的,因为不可能每个人都会仔细的敲代码并审查代码;那么如果出现这些问题时,有什么弥补手段了?
这时候在项目开发中,使用内存检测模块就非常有必要了。
二、基本原理
要使用一块新内存,要么从栈上分配,要么从堆上分配,如果是从堆上分配,那么就记录申请好的内存起始地址,分配的大小,文件名和行号(哪个文件的哪一行调用了分配函数),
如果是释放堆上的内存,同样记录释放的地址,文件名和行号(哪个文件的哪一行调用了释放函数),这样对所有的分配和释放操作进行记录的话,就可以解决一些内存操作问题,
如内存泄露,内存重复释放等;大体结构如下图所示:
三、应用开发
C语言中的内存申请函数为malloc,内存释放函数为free,如果我们在产品开发中直接使用这两个函数,那么又怎么会得到文件名和行号了?因此需要对malloc和free函数进行封装,
使用宏进行封装,如
#define DAWEN_MALLOC(_size) my_malloc(_size,__FILE__,__LINE__)
#define DAWEN_FREE(_pointer) my_free(_pointer,__FILE__,__LINE__)
其中__FILE__,__LINE__宏为系统自定义的宏,表示当前代码运行处的文件名和行号,然后,在my_malloc函数中使用malloc系统函数,在my_free函数中使用free系统
函数,这样就可以记录一些信息了。所以在开发时,一律使用my_malloc来申请内存,使用my_free来释放内存。
四、内存操作注意事项
我在这里写了C语言开发中的指针操作注意释放,希望与大家一起学习:
1、申请一段内存后,应对该内存内存进行初始化,如调用memset进行清零操作
2、申请内存后,在进行操作之前,应对申请后的指针进行空值判断
3、释放指针后,该指针必须赋值为NULL,当然赋值操作这个操作在my_free函数中进行,所以my_free函数的参数为二级指针
4、尽量坚持谁申请谁释放的规则,如果不是,则组成员应该协商或者代码加注释说明
五、备注
关于内存覆盖和内存访问越界,一直找不到好的方法检测。。郁闷中。。。。。