常见的动态内存错误
前言:
上一篇文章介绍了C语言中动态内存的四个函数,其中malloc与calloc是用来申请动态内存空间的函数,它们之间的区别就在于calloc函数申请的空间会自动初始化为0,free函数一般是和malloc,calloc一起使用的,free主要是用来释放申请的动态内存空间。注意,free函数的参数指针只能是申请的动态空间的起始地址,且free函数只能释放动态内存空间。realloc函数是用来改变申请的动态内存大小的。
上述是对上篇介绍的函数的简单复习,如果有遗忘的,可以看看上篇文章温习一遍
本篇文章将介绍一些与动态内存有关的常见错误!希望能够帮助大家规避这些问题。
错误一:对NULL指针的解引用操作
前面说过在开辟动态内存空间的时候,如果开辟失败,就会返回NULL。所以,如果在开辟动态内存空间的时候,没有提前检验一下是否开辟成功,就会出现对NULL指针解引用操作
比如说:
#include <stdio.h>
int main()
{
int* p = (int*)malloc(40);
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
}
上诉代码中,我们使用malloc开辟了40字节的动态内存空间,但是没有检验是否开辟成功,便直接使用,也就是这里面的*(p+i),如果开辟失败,这里的p就是空指针,对空指针进行解引用操作,是无效的。
正确做法:
在使用malloc函数申请空间后,检查一下是否开辟成功。
int* p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc")//打印开辟空间失败的原因
return 1;
}
注意:在开辟动态内存空间的时候,一定要记得进行检验是否开辟成功。
错误二:对动态开辟空间的越界访问
关于动态内存的开辟,并不是说动态内存就不需要在意大小了,你开辟多少空间,就只能用那些空间。
int* p = (int*)malloc(40);
开辟40个字节的空间
#include <stdio.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
}
错误1:
for (i = 0; i <= 10; i++)
{
*(p + i) = i;
}
上诉代码中,i 循环了11次,但是我们使用malloc总共就开辟了40个字节,也就是10个整型的空间,这样就会出现越界访问的情况。
错误2:
for (i = 0; i < 40; i++)
{
*(p + i) = i;
}
混淆了malloc函数参数的单位,以为是开辟了40个整型的空间。
错误三:对非动态内存开辟使用free释放
关于free,我们要知道它只能用来释放动态内存开辟的空间。但是有时候由于写的代码过多或者过于混乱,可能会出现适用free释放非动态内存开辟的空间,这样就会造成错误。
比如说:
#include <stdio.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
int arr[10] = { 0 };
p = arr;
free(p);
p = NULL;
return 0;
}
上述代码中,你将arr的空间存到了p中,此时p中存放的是栈区的空间,栈区的空间使用free释放,程序会直接崩溃。
错误四:使用free释放一块动态内存开辟的一部分
这句话是什么意思呢?来看下面这个代码
#include <stdio.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
for (int i = 0; i < 5; i++)
{
*p = i;
p++;
}
free(p);
p = NULL;
return 0;
}
上述代码中我们创建了10个整型的空间,然后循环只循环5个整型将0~4个填入p中,每次循环p就+1,等到循环结束的时候,p指向我们开辟的动态内存的中间。
此时使用free释放,你会发现一个问题,p现在不指向你开辟的这块空间的起始地址了,那怎么释放?能够只释放一部分吗?
p目前指向空间的中间地址,是没法被释放的。
正确做法:
在动态内存的使用中,一般不会让存放起始地址的指针亲自去遍历的,可以在创建一个指针变量来遍历。
循环的时候,不改变p,代码可以这么写
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
for (int i = 0; i < 5; i++)
{
*(p + i) = i+1;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
错误五:对同一块动态内存多次释放
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
for (int i = 0; i < 5; i++)
{
*(p + i) = i+1;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(p + i));
}
free(p);
//
free(p);
p = NULL;
return 0;
}
在写代码的过程中连续对一块空间进行多次free,程序就会崩溃
错误六:动态开辟内存忘记释放
这个错误就比较好了理解了 ,开辟了动态内存,但是最后没有使用free释放
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
for (int i = 0; i < 5; i++)
{
*(p + i) = i+1;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(p + i));
}
//free(p);
//p = NULL;
return 0;
}
原文地址:https://blog.csdn.net/2401_85010100/article/details/143722987
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!