目录
一、常见的动态内存错误
1、对NULL指针的解引用操作
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
如果malloc失败了,那么p就是空指针,对空指针进行解引用操作一定不行,所以要提前有判断。
2、对动态开辟内存的越界访问
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(5 * sizeof(int));
if (p == NULL)
{
return 0;
}
else
{
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
}
free(p);
p = NULL;
return 0;
}
只开辟了5个整型的空间,但是要循环10个,所以造成了越界访问。
3、对非动态开辟空间使用free
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a = 10;
int* p = &a;
*p = 20;
free(p);
p = NULL;
return 0;
}
动态分配出现错误有时候会卡死。
4、使用free释放动态内存的一部分
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 0;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*p++ = i;
}
free(p);
p = NULL;
return 0;
}
当p逐渐增加,最后指向了最后一个元素地址,此时释放,也就是释放此时p之后的空间,这不行,会出现错误,free只能从起始位置开始释放,不能从某一点开始释放。
5、对同一块动态内存多次释放
free(p);
free(p);
p = NULL;
每次释放完都赋值空指针,再者就是写上注释。
6、动态开辟内存忘记释放
要不内存泄露,内存一直被使用,直到被装满,电脑越来越卡。
二、练习
1、内存泄漏
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
这里面有两个问题:
运行代码程序会出现崩溃的现象
程序存在内存泄漏的问题
str以值传递的形式给p
p是GetMemory函数的形参,只能函数内部有效,等此函数返回之后,动态开辟内存尚未释放并且无法找到,所以造成内存泄露
进入test函数后,str是传值方式,p相当于str的一个临时拷贝,传过去空指针后,动态开辟内存,把这块空间的首元素地址赋值给p指针,所以p也就指向了这个空间。但是这个函数没有返回值,导致开辟完后,str还是一个空指针,这时候进行拷贝相当于解引用空指针,所以程序崩溃。
要改正的话
void GetMemory(char** p)
{
*p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
}
或者
char* GetMemory(char* p)
{
p = (char*)malloc(100);
return p;
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
}
下一篇继续写2。
结束。