3.1对NULL指针的解引用操作
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(20);
//可能会出现对NULL指针的解引用操作
int i = 0;
for (i = 0; i < 5; i++)
{
p[i] = i;
}
free(p);
p = NULL;
return 0;
}
当我们这样写代码的时候,可以看到编译器报了一个警告:取消对NULL指针“p”的引用。
就是说,如果 p 是NULL指针的话,0+0 再解引用(此时i=0),就会出现对NULL指针的解引用操作,这样是非常危险的。所以malloc函数的返回值要判断。
3.2对动态开辟空间的越界访问
#include <string.h>
#include <errno.h>
#include <stdio.h>
int main()
{
int i = 0;
int* p = (int*)malloc(20);
if (NULL == p)
{
printf("%s\n", strerror(errno));
return 1;
}
//越界访问
for (i = 0; i < 10; i++)
{
p[i] = i;
}
free(p);
return 0;
}
当出现对动态开辟空间的越界访问的时候,程序运行起来之后就会崩溃(什么都不打印,过几秒后自动结束运行)。
3.3对非动态开辟内存使用free释放
int main()
{
int arr[10] = { 1,2,3,4,5 };
int* p = arr;
//......对arr数组进行了什么什么操作
free(p);
p = NULL;
return 0;
}
如果你某一天写代码的时候,喝了点小酒,对指向一个数组的指针进行了free,那么程序同样也会崩溃:
3.4 使用free释放一块动态开辟内存的一部分
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
for (i = 0; i < 5; i++)
{
*p++ = i + 1;
}
free(p);
p = NULL;
return 0;
}
这时p已经不再指向动态内存的起始位置,而是指向了中间位置,这是对p进行释放,程序也会崩溃:
3.5对同一块动态内存多次释放
int main()
{
int* p = (int*)malloc(20);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//使用
free(p);
//释放
free(p);
p = NULL;
return 0;
}
这时程序也会崩溃:(但是如果之前把p置为NULL了,就不会崩溃,因为free空指针的话,什么也不会发生)
3.6动态开辟内存忘记释放(内存泄露)
对于malloc,calloc,realloc函数所申请的空间 ;如果不想使用,需要free释放,如果不适用free释放,程序结束后,也会由操作系统回收;但是,如果不使用free释放,程序也没有结束,就会导致内存泄漏。