3. 常见的动态内存错误
对NULL指针的解引用操作
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
对动态开辟空间的越界访问
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}
对非动态开辟内存使用free释放
void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
//这样不可以,会报错,非堆上的动态内存不能用free来释放
}
使用free释放一块动态开辟内存的一部分
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置,程序会挂掉
//free释放的是p指向的空间,p必须指向所要释放空间的起始地址
}
对同一块动态内存多次释放
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放,会报错
}
动态开辟内存忘记释放(内存泄漏)
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
//这里应该free掉开辟的动态内存空间
while(1);
}
忘记释放不再使用的动态开辟的空间会造成内存泄漏。
切记: 动态开辟的空间一定要释放,并且正确释放 。
4. 几个经典的笔试题
题目1:
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void) {
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
运行Test会有什么结果?
答案是会程序会挂掉
代码分析:
错误原因;
①str传给p的时候,是值传递,p是str的临时拷贝,所以当malloc开辟的空间起始地址放在p中时,不会影响str,str依然为NULL
②当str时NULL,strcpy想把hello world拷贝到str指向的空间时,程序就崩溃了,因为NULL指针指向的空间是不能直接访问的
图解:*
代码改正:
题目2:
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
运行Test会有什么结果?
答案是
代码分析:
错误原因;
①p是局部变量(局部变量是存在栈区的),函数调用完之后就会随着函数空间的销毁而销毁,将内存空间还给操作系统
②返回的p实际上已经是一个野指针了,指向的是未知的空间
图解:
代码改正:
题目3 :
void GetMemory(char **p, int num) {
*p = (char *)malloc(num);
}
void Test(void) {
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
运行Test会有什么结果?
答案是
内存泄漏!!!!
代码分析:
错误原因;
①malloc申请了内存空间,是在堆区上的,是不会自动销毁的
②如果在使用完成之后没有free掉这块空间,会造成内存泄漏,内存泄漏是指程序中已动态分配的的堆内存,由于某些原因无法释放或者未释放,造成的内存浪费。
图解:
代码改正:
题目4 :
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
运行Test会有什么结果?
答案是
数据非法访问
代码分析:
错误原因;
①free完之后没有将指针置空,造成了野指针的存在
②野指针会导致非法访问行为
图解:
代码改正:
版权声明:本文为CSDN博主「敲代码的布莱恩特」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/DerrickWestbrook/article/details/120483621