c的动态内存管理
一、动态内存分配
1、 c语言中动态内存分配的步骤:
(1) 用mallocl类的函数分配内存;
(2) 用这些内存支持应用程序;
(3) 用free函数释放内存
例如:
2、 内存泄露
如果不再使用已分配的内存却没有将其释放,就会发生内存泄露,导致内存泄露的情况可能如下:
(1) 丢失内存地址
在上图中,pi重新分配地址,原来指向的地址丢失。
Name指向的初始内存地址丢失
(2) 应该调用free函数却没有调用
对于这种情况,尤其需要注意:指向结构体的情况,如果一个结构体内部有动态指针,在释放结构体指针的时候需要释放结构体内部的动态指针。
3、 动态分配内存函数
(1) malloc函数从堆上分配一块内存,所分配的字节数由该函数唯一的参数指定,返回值是void指针,如果内存不足,就会返回NULL,否则返回首字节地址,新分配的内存包含垃圾数据。
初始化静态或全局变量时不能调用函数,(但是貌似用vs2012没有报错)
(2) 使用calloc分配内存
Calloc会在分配的同时清空内存,清空内存的意思是将其内容置为二进制0.函数的原型是:
Calloc函数会根据numElements和elementSize两个参数的乘积分配内存,并返回一个指向内存的第一个字节的地址,如果分配失败,返回NULL。不用calloc的话,用malloc函数和memset函数可以得到同样的结果,如下
(3) 使用realloc分配内存
我们可能需要时不时地增加或减少为指针分配的内存,如果需要一个变长数组,这种做法尤其有用,realloc函数会重新分配内存,原型如下:
Realloc函数返回指向内存块的首地址,该函数接收两个参数,第一个参数是原来内存块的指针,第二个参数是请求新的内存块地址大小。如果成功创建,原来的指针指向的内存被释放。如果新的内存小于原来的内存,多余的内存会还给堆,不能保证多余的内存会被清空;如果新的内存比原来内存空间大,旧的内存数据会被幅值到新的内存数据。
(4)三种内存动态分配函数比较
(4) 重复释放内存
两个指针同时指向一块动态分配的内存,只需要释放一个。
(5) 迷途指针
如果内存已经释放,而指针还在引用原始内存,这样的指针就是迷途指针,迷途指针没有指向有效对象,有时候也称为过早释放。
有一种迷途指针的情况更难觉察:一个以上的指针引用同一内存区域而其中一个指针被释放,如下所示,p1和p2都引用同一块内存区域(称为指针别名),不过p1被释放了:
(6) 处理迷途指针
i、释放指针后置为NULL,后续使用这个指针会终止应用程序。
ii、写一个特殊的函数代替free函数。
iii、使用第三方工具检测迷途指针。