常见的内存错误及其对策
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2018/10/7
常见的内存错误及其对策
常见错误2: 内存分配成功,但是尚未初始化就引用它 起因 没有初始化的观念 误以为内存的默认值全为0 解决对策 即使是赋0值也不可省略,不要嫌麻烦
2018/10/7
常见的内存错误及其对策
常见错误3: 内存分配成功,并且已经初始化,但操作越过
2018/10/7
if (pszHisName == NULL) { free(pszMyName); free(pszHerName); return; }
… …
free(pszMyName); free(pszHerName); free(pszHisName); return;
常见的内存错误及其对策
错在哪里!
一个例子
void Init(void) { pszMyName=(char*)malloc(256); if (pszMyName == NULL) { return; } pszHerName=(char*)malloc(256); if (pszHerName == NULL) { free(pszMyName); return; } } pszHisName=(char*)malloc(256);
每次遗留内存垃圾的多少 代码被调用的次数
2018/10/7
常见的内存错误及其对策
解决对策 在需要的时候才malloc,并尽量减少malloc的次数
malloc的执行效率就不高,过多的malloc使程序性能下降 能用自动变量解决的问题,就不要用malloc来解决 malloc一般在大块内存分配和动态内存分配时使用
了内存的边界
例如:使用数组时经常发生下标“多1”或者
“少1”的操作
解决对策: 在for语句中,注意循环次数不要搞错
2018/10/7
常见的内存错误及其对策
常见错误4: 忘记释放内存,造成内存泄漏(Memory Leak) “内存泄露”一词类似“原料泄露” 泄露出去的原料不能被利用,导致生产过程中
常见的内存错误及其对策
常见错误1: 内存分配未成功,却使用了它 起因 没有意识到内存分配会不成功 编程新手容易犯 解决对策 在使用内存之前,检查指针是否为空指针(NULL)
if (p == NULL) { printf("No enough memory!\n"); exit(0); }
释放了内存,却继续使用它 基本特征 代码访问了不该访问的内存地址
2018/10/7
void GetInput(char* s) { scanf("%s", s); } 2018/10/7
常见的内存错误及其对策
#include <stdio.h> #include <stdlib.h>
void GetInput(char *p) { p = (char *)malloc(100); }
程序崩溃,函数不能传递动态分配的内存?
void GetInput(char **p) { *p = (char *)malloc(100); 2018/10/7 }
常见的内存错误及其对策
常见错误5解决对策 尽量把malloc集中在函数的入口处,free集
中在函数的出口处
如果free不能放在函数出口处,则指针free后
原料不足
好比借东西不还 如果申请来的内存不用,别的程序也不能用,
就好像这块内存泄露出去一样,造成浪费
2018/10/7
常见的内存错误及其对策
特征 含有这种错误的函数,每被调用一次,就丢失
一块内存(制造内存垃圾) 刚开始时,系统内存充足,看不到任何错误 当系统运行相当一段时间后,就会突然死掉, 出现提示:内存耗尽 需长期稳定运行的服务程序对内存泄漏最敏感 严重程度取决于
常见错误5: 释放了内存,却继续使用它
起因: 指针所指的内存被释放以后,并不表示指针会
消亡 其地址仍然不变(非NULL),只是该地址对 应的内存是垃圾 指向垃圾内存的指针是“野指针”
… free(ptr); if (ptr != NULL) //不起作用 { … }
2018/10wk.baidu.com7
常见的内存错误及其对策
char* GetInput(void) { char s[80]; scanf("%s", s); return s; }
错在哪里!
warning C4172: returning address of local variable or temporary 输出乱码 不能把局部变量的地址作为返 回值返回 函数返回后,局部变量被释放 ,该地址的内存会被挪做它用
重复使用malloc申请到的内存 尽量让malloc和与之配套的free在一个函数或模块
内
尽量把malloc集中在函数的入口处,free集中在函数的出 口处
以上做法只能尽量降低产生泄露的概率。完全杜 绝内存泄露,关键要靠程序员的细心与责任感
2018/10/7
一个例子
void Init(void) { pszMyName=(char*)malloc(256); if (pszMyName == NULL) { return; } if (pszHisName == NULL) { return; } … …
立即设置为NULL
不要把局部变量的地址作为返回值返回,因为
该内存在函数体结束时被自动销毁
指针要么初始化为NULL,要么是其指向合法的
内存
2018/10/7
非法内存操作
起因 内存分配未成功,却使用了它 内存分配成功,但是尚未初始化就引用它 内存分配成功,并且已经初始化,但操作越过
了内存的边界
pszHerName=(char*)malloc(256); if (pszHerName == NULL) { return; return; } } pszHisName=(char*)malloc(256);
2018/10/7
free(pszMyName); free(pszHerName); free(pszHisName);
常见的内存错误及其对策
常见错误2: 内存分配成功,但是尚未初始化就引用它 起因 没有初始化的观念 误以为内存的默认值全为0 解决对策 即使是赋0值也不可省略,不要嫌麻烦
2018/10/7
常见的内存错误及其对策
常见错误3: 内存分配成功,并且已经初始化,但操作越过
2018/10/7
if (pszHisName == NULL) { free(pszMyName); free(pszHerName); return; }
… …
free(pszMyName); free(pszHerName); free(pszHisName); return;
常见的内存错误及其对策
错在哪里!
一个例子
void Init(void) { pszMyName=(char*)malloc(256); if (pszMyName == NULL) { return; } pszHerName=(char*)malloc(256); if (pszHerName == NULL) { free(pszMyName); return; } } pszHisName=(char*)malloc(256);
每次遗留内存垃圾的多少 代码被调用的次数
2018/10/7
常见的内存错误及其对策
解决对策 在需要的时候才malloc,并尽量减少malloc的次数
malloc的执行效率就不高,过多的malloc使程序性能下降 能用自动变量解决的问题,就不要用malloc来解决 malloc一般在大块内存分配和动态内存分配时使用
了内存的边界
例如:使用数组时经常发生下标“多1”或者
“少1”的操作
解决对策: 在for语句中,注意循环次数不要搞错
2018/10/7
常见的内存错误及其对策
常见错误4: 忘记释放内存,造成内存泄漏(Memory Leak) “内存泄露”一词类似“原料泄露” 泄露出去的原料不能被利用,导致生产过程中
常见的内存错误及其对策
常见错误1: 内存分配未成功,却使用了它 起因 没有意识到内存分配会不成功 编程新手容易犯 解决对策 在使用内存之前,检查指针是否为空指针(NULL)
if (p == NULL) { printf("No enough memory!\n"); exit(0); }
释放了内存,却继续使用它 基本特征 代码访问了不该访问的内存地址
2018/10/7
void GetInput(char* s) { scanf("%s", s); } 2018/10/7
常见的内存错误及其对策
#include <stdio.h> #include <stdlib.h>
void GetInput(char *p) { p = (char *)malloc(100); }
程序崩溃,函数不能传递动态分配的内存?
void GetInput(char **p) { *p = (char *)malloc(100); 2018/10/7 }
常见的内存错误及其对策
常见错误5解决对策 尽量把malloc集中在函数的入口处,free集
中在函数的出口处
如果free不能放在函数出口处,则指针free后
原料不足
好比借东西不还 如果申请来的内存不用,别的程序也不能用,
就好像这块内存泄露出去一样,造成浪费
2018/10/7
常见的内存错误及其对策
特征 含有这种错误的函数,每被调用一次,就丢失
一块内存(制造内存垃圾) 刚开始时,系统内存充足,看不到任何错误 当系统运行相当一段时间后,就会突然死掉, 出现提示:内存耗尽 需长期稳定运行的服务程序对内存泄漏最敏感 严重程度取决于
常见错误5: 释放了内存,却继续使用它
起因: 指针所指的内存被释放以后,并不表示指针会
消亡 其地址仍然不变(非NULL),只是该地址对 应的内存是垃圾 指向垃圾内存的指针是“野指针”
… free(ptr); if (ptr != NULL) //不起作用 { … }
2018/10wk.baidu.com7
常见的内存错误及其对策
char* GetInput(void) { char s[80]; scanf("%s", s); return s; }
错在哪里!
warning C4172: returning address of local variable or temporary 输出乱码 不能把局部变量的地址作为返 回值返回 函数返回后,局部变量被释放 ,该地址的内存会被挪做它用
重复使用malloc申请到的内存 尽量让malloc和与之配套的free在一个函数或模块
内
尽量把malloc集中在函数的入口处,free集中在函数的出 口处
以上做法只能尽量降低产生泄露的概率。完全杜 绝内存泄露,关键要靠程序员的细心与责任感
2018/10/7
一个例子
void Init(void) { pszMyName=(char*)malloc(256); if (pszMyName == NULL) { return; } if (pszHisName == NULL) { return; } … …
立即设置为NULL
不要把局部变量的地址作为返回值返回,因为
该内存在函数体结束时被自动销毁
指针要么初始化为NULL,要么是其指向合法的
内存
2018/10/7
非法内存操作
起因 内存分配未成功,却使用了它 内存分配成功,但是尚未初始化就引用它 内存分配成功,并且已经初始化,但操作越过
了内存的边界
pszHerName=(char*)malloc(256); if (pszHerName == NULL) { return; return; } } pszHisName=(char*)malloc(256);
2018/10/7
free(pszMyName); free(pszHerName); free(pszHisName);