共计 1344 个字符,预计需要花费 4 分钟才能阅读完成。
常见内存谬误
构造体成员指针未初始化
构造体成员指针未调配足够的变量
内存调配胜利,但并未初始化
内存操作越界
例子 42-1:
#include "stdio.h"
#include "malloc.h"
void test(int* p,int size)
{
int i = 0;
for(i = 0; i < size; i++)
{printf("%d\n",p[i]);
}
// free(p);
}
void func(unsigned int size)
{int *p = (int*)malloc(size *sizeof(int));
int i = 0;
if(size % 2 != 0)
{return;}
for(i = 0; i < size; i++)
{p[i] = i;
printf("%d\n",p[i]);
}
free(p);
}
int main()
{int* p = (int*)malloc(5 * sizeof(int)); // 在 main 函数外面申请的动态内存,就要在 main 函数外面开释
test(p , 5);
free(p);
func(9);
func(9);
return 0;
}
输入后果:
func 函数会产生内存透露,如果是基数就会间接 return,导致内存没有开释,造成内存透露
例子 42-2:
#include "stdio.h"
#include "malloc.h"
struct Demo
{char *p;}
int main()
{
struct Demo d1;
struct Demo d2;
char i = 0;
for(i = 'a';i < 'z';i ++)
{d2.p[i] = 0;
}
d2.p = (char*)calloc(5,sizeof(char));
printf("%s\n",d2.p);
for(i = 'a';i < 'z';i ++) // 内存越界
{d2.p[i] = i;
}
free(d2.p);
return 0;
}
内存操作的规定
规定一:
动态内存申请之后,应该立刻查看指针值是否为 NULL,避免应用 NULL 指针。
int* p = (int*)malloc(56);
if(p != NULL)
{
}
free(p);
规定二:
free 指针之后必须立刻赋值为 NULL
int* p = (int*)malloc(20);
free(p);
p = NULL;
//......
//......
if(p != NULL)
{}
规定三:
任何与内存操作相干的函数必须带长度信息
void print(int* p,int size)
{
int i = 0;
char buf[128] = {0};
snprintf(buf,sizeof(buf),"%s","D.T.Software");
for(i = 0;i < size; i++)
{printf("%d\n",p[i]);
}
}
规定四:
malloc 操作和 free 操作必须匹配,避免内存透露和屡次开释。不要跨函数开释内存。
void func()
{int* p = (int*)malloc(20);
free(p);
}
int main()
{int* p = (int*)malloc(20);
func();
free(p);
return 0;
}
小结:
内存谬误的实质源于指针保留的地址为非法值
指针变量未初始化,保留随机值
指针运算导致内存越界
内存透露于 malloc 和 free 不匹配
当 malloc 次数多于 free 时,产生内存透露
当 malloc 次数少于 free 时,程序可能解体
正文完