1、常见的内存错误
- 结构体成员指针未初始化
- 结构体成员指针未分配足够的内存
- 内存分配成功,但并未初始化
- 内存操作越界
结构体成员指针的初始化一般都是 malloc 一段动态内存,或者指向已有的内存空间
#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));
test(p, 5);
free(p);
func(9);
func(10);
return 0;
}
#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++)
{
d1.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;
}
2、内存操作的交通规则
- 动态内存申请之后,应该立即检查指针值是否为NULL,防止使用NULL指针
int* p = (int*)malloc(56);
if (p != NULL)
{
//Do something here!
}
free(p);
- 当你free了指针后就必须立即赋值为NULL
- 任何与内存相关的函数都必须带长度信息
- malloc了后就必须free,在main()里面申请的动态内存就在main里面释放,在func()里面申请的动态内存就在func里面释放。主要是怕main()里面申请的动态内存如果在函数里面释放,下次调用函数就造成了重复释放。
小结:
- 内存错误的本质来源于指针保存的地址为非法值
— 指针变量未初始化,保存随机值
— 指针运算导致内存越界 - 内存越界源于 malloc 和 free 不匹配
— malloc 次数多于 free ,产生泄漏
— malloc 次数少于 free ,程序崩溃