内存管理常见的6种问题
1.指针没有指向一块合法的地址,而指向的是乱码地址,对指针赋值时改变了其他地方的内容引起错乱。
对策:
(1)在定义指针时,同时初始化为NULL,用完指针后也将指针变量的值设置为NULL;
(2)使用指针时,给指针指向的位置申请一块新内存,eg:psu=(struct student*)malloc(sizeof(struct student));这块内存要足够大sizeof(struct student*)就只有4个字节,不是结构体的大小。
(3)函数的入口校验,debug版本中在函数入口处使用assert(NULL != p)对参数进行校验。注意:包含assert.h文件,如果括号值为假,则程序终止运行,并提示出错,如果括号值为真,则继续运行后面的代码。
如果是用malloc或new来申请内存,应该用if (p ==NULL) 或if (p! = NULL)进行防错处理。
2.为指针分配的内存太小,eg:字符串常量后面有“/0”占一个字节;
3.内存分配成功,但未初始化
有时会误把未初始化的值当作0,带入函数中导致错误,所以在定义一个变量时,第一件事就是初始化。注意:不初始化的指针是随机指向一个地址。
eg:
指针:
char* p = NULL;
char *p =(char*)malloc(sizeof(char)*num);
数组:
int a[10] = {0}; or
int a[10] = memset(a,0,sizeof(a));
4.内存越界:
经常在操作数组或者指针时出现“多1”或“少1”的问题;
eg:for循环语句中,循环次数很容易搞错,导致数组操作越界。
5.内存泄漏:
(1)内存泄漏会产生在堆上,也就是说malloc 或new操作分配的内存。如果用完后没有及时free或者delete, 这块内存就无法释放,直到整个程序结束;
(2)
A:
malloc原型:(void*)malloc(int size)
char* p = (char*)malloc(100);
//在malloc函数申请内存后,必须用if(NULL!= p)语句验证内存是否分配成功。
if(NULL!= p);
// 验证内存是否分配成功
strcpy(p,"hello");
B:
free(p);
p=NULL;
// free解除内存地址和p之间的联系,但p依然保存地址值,内存依然保存原来的值
//如果没有上一句,则p会变成野指针
(3)A: malloc两次只free一次会内存泄漏;
B: malloc一次但free两次会产生未知错误。
C: 程序中malloc的使用次数和free的必须相等,否则必有错误。
D: 常出现的位置:内存泄漏注意发生在循环使用malloc函数时。
6.内存已经被释放了,但是继续通过指针来使用;
有三种情况:
(1)使用 free 或者 delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。
(2)函数的return函数语句写错了,注意不能返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。
(3)程序中的对象调用关系过于复杂,应该重新设计数据结构。
7.养成规范,避免问题