C语言学习(三十四)---动态内存常见错误总结

上节内容中,我们学习如何规范的申请和使用动态内存,其实是很重要的一环。

在大的程序中,应该注意这些细节问题,不然就会对其他的程序猿们产生影响,因为大的程序不可能交由一个人完成,所以,你编写的代码不够规范就有可能对后续的编写工作产生不良的影响。

今天,我们将学习在动态内存中常见的错误,好了,话不多说,开整!!!!!

动态内存中的常见错误

未经判定就使用

未经判定也就是说,没有判断向内存中的栈区申请空间这个操作是否成功,就使用了该部分内存,这显然是不合理的,极易产生错误,如以下代码:

#include
#include
int main()
{
    int* arr = (int*)malloc(10*__INT_MAX__);
    int i = 0;
    for(i=0;i<10;i++)
    {
        *(arr+i) = i;
        printf("%d ",*(arr+i));
    }
    free(arr);
    arr =  NULL;
    return 0;
}

其中的_INT_MAX_代表着16进制数0x7fffffff,因此如此大的空间或许我们没有申请成功,但未经判断就在下面进行了使用,结果程序崩溃,如下:

在这里插入图片描述

如果我们进行判定,就会避免这个错误的产生,如下所示代码:

#include
#include
#include
int main()
{
    int* arr = (int*)malloc(10*(__INT_MAX__));
    int i = 0;
    if (arr == NULL)
    {
        printf("%s\n",strerror(errno));
    }
    else
    {
        for(i=0;i<12;i++)
    {
        *(arr+i) = i;
        printf("%d ",*(arr+i));
    }
    }
    free(arr);
    arr = NULL;
    return 0;
}

编译查看结果:
在这里插入图片描述
编译器提醒我们,没有足够的动态内存空间,这样就不会执行赋值代码,程序自然就不会奔溃,因此,申请到的动态内存空间在使用前进行判定十分重要

越界访问

越界访问这个词,我们不是第一次听说了,在数组中就存在着越界访问的问题,也就是没有那么大的地方,你非要访问那么大的地方,导致程序产生了错误,如以下代码:

#include
#include
#include
int main()
{
    int* arr = (int*)malloc(40);
    int i = 0;
    if (arr == NULL)
    {
        printf("%s\n",strerror(errno));
    }
    else
    {
        for(i=0;i<11;i++)
    {
        *(arr+i) = i;
        printf("%d ",*(arr+i));
    }
    }
    free(arr);
    arr = NULL;
    return 0;
}

从上述代码中我们可以看到,向动态内存在申请了40字节的空间,但是在赋值是我们缺赋值了11个整型元素也即44字节,此时就会产生越界访问的问题

但是在vscode下仍然没报错,看样子在这个编译器下,可能是编译器比较强(我猜的),因此就不演示了。

对非动态内存的释放

你明明没有使用动态内存定义,却对变量进行空间释放,就会产生错误,如以下代码:

#include
#include
int main()
{
    int a  = 10;
    int* p = &a;
    free(p);
    p = NULL;
    return 0;
}

只是在栈区上定义了一个变量,你却对他进行了内存释放,显然不合理,因此也会产生错误,但是该从代码在VScode下,也正常编译了,因此在Linux下演示效果,编译结果如下:

C语言学习(三十四)---动态内存常见错误总结_第1张图片
可见,对非动态内存进行空间释放也会产生问题

动态释放部分空间

先上代码如下:

#include
#include
int main()
{
    int* p = (int*)malloc(40);
    int i = 0;
    if (p == NULL)
    {
        return 0;
    }
    else
    {
    for(i=0;i<5;i++)
    {
        *p++ = i;
    }
    }
    free(p);
    p = NULL;
    return 0;
}

我们进行分析:在申请了动态内存后,判断,进行循环赋值,然后进行释放,但是其实在释放是就产生了问题,如下图:

C语言学习(三十四)---动态内存常见错误总结_第2张图片
再赋值完后,p指向的已经不再是最初的地址,因此对对其进行释放,将会释放此地址后的40个字节的内存,我们在Linux下编译运行,如下:
C语言学习(三十四)---动态内存常见错误总结_第3张图片
可见,释放一部分动态内存空间也会产生错误

对同一块内存进行多次释放

这个就比较好理解了,你再释放完后,又给人释放了,这叫什么事,代码如下:

#include
#include
int main()
{
    int* p = (int*)malloc(40);
    if (p == NULL)
    {
        return 0;
    }
    else
    {
        int i = 0;
        for(i=0;i<10;i++)
        {
            *(p+i) = i;
        }
    }
    free(p);
    free(p);
    p = NULL;
    return 0;
}

查看结果:
C语言学习(三十四)---动态内存常见错误总结_第4张图片

忘记释放动态空间

这个就更好理解了,在上节课就介绍过了,就不再此处重复讲解了,请大家回看上节内容

上述内容即使今天的全部内容了,感谢大家的观看。
如果方便,辛苦大家点个赞和关注哦!
您的点赞或评论或关注是对我最大的肯定,谢谢大家!!!

你可能感兴趣的:(C语言学习,c语言,学习,开发语言)