C语言小tip之动态内存常见错误

hello各位小伙伴们,上期我们讲到了动态内存的基础的知识,这期让我们学习一下动态内存常见的错误。

一、未判断动态内存是否开辟成功

我们之前了解到malloc如果在动态内存开辟成功的情况下,会返回开辟空间的首地址,开辟失败会反回空指针NULL。如果未判断就对动态内存进行操作,就会造成错误!

cpp 复制代码
#include<stdio.h>
int main ()
{
    int*p = (int*)malloc(40);
    *p = 20;
    ......
}

所以我们要加上判断语句来看看是否开辟成功

cpp 复制代码
#include<stdio.h>
int main ()
{
    int*p = (int*)malloc(40);
    if(p=NULL)
    {
        perror("malloc");
        return 1;//未开辟成功的情况下,提前返回结束程序
    }
    ......
   
}

二、对所开辟的动态内存越界访问

我们以这段代码为例:

cpp 复制代码
#include<stdio.h>
int main ()
{
    int *p = (int*)malloc(40);//开辟40个字节的空间
    if(p==NULL)
    {
        perror("malloc");
        return 1;
    }
    int i = 0;
    for (i = 0;i<=10;i++)
    {    
        *(p+i) = i;
    }
    ......
}

我们在对所开辟的40个字节大小空间进行赋值时,只能赋值10个整型,但越界访问进行了11个整型的赋值!,这样就会导致动态内存的越界访问!

三、对非动态内存进行释放

上期我们讲到,在使用free释放空间的时候,释放对象必须是动态内存所开辟的空间!不能对非动态内存释放空间。

cpp 复制代码
#include<stdio.h>
int main ()
{
    int a = 10;
    int *pa = &a;
    free(pa);
    pa = NULL;
    ......   
}

四、使用free释放动态内存的一部分空间

cpp 复制代码
#include<stdio.h>
int main ()
{
    int *p = (int*)malloc(40);
    if(p==NULL)
    {    
        perror("malloc");
        return 1;
    }
    int i = 0;
    for(i = 0;i<10;i++)
    {
        *p = i;
        p++;
    }
    free(p);
    p = NULL:
    return 0;
}

在for循环中看似确实能对所开辟的空间进行赋值,由原来的*(p+i)的形似改为使用p++的形式,通过是地址自加来实现,但free函数在释放内存的时候,要从释放内存的首地址开始,使用p++的形式会导致释放内存的时候只会释放一部分内存!

五、对一块内存进行多次释放

在使用malloc函数进行动态内存开辟的时候,最后不释放内存万万不可,释放多次也是不可以的!

例如:

cpp 复制代码
#include<stdio.h>
int main ()
{
    int *p = (int*)malloc(40);
    if(p==NULL)
    {
        perror("malloc");
        return 1;
    }
    int i = 0;
    for(i = 0;i<10;i++)
    {
        *(p+i) = i;
    }
    free(p);
    ......
    free(p);
    return 0;
}

如果我们在编程的时候不得已要多次释放空间,使用多次free函数,要注意在每次释放完后要将指针变量置为空指针!,在进行第二次释放的时候就不会报错了。

六、动态内存忘记释放或者不能释放导致的内存泄露

cpp 复制代码
#include<stdio.h>
int main ()
{
    int *p = (int*)malloc(40);
    if(p==NULL)
        return 1;
    while(1);
    return 0;
}

此时这种情况会在忘记释放内存后导致内存的泄露!

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
void test()
{
    int *p = (int*)malloc(40);
    if(p==NULL)
        return 1;
}
int main ()
{
    test(); 
    return 0;
}

在这种情况下,在进入main函数之前局部变量会销毁!无法对在test函数中所创建的局部指针变量p进行释放,这样就会造成空间的泄露!

解决方法:在test函数中返回所创建的指针变量,在main函数中进行接收,并释放然后在置为空指针!内存泄露会导致可使用的空间越来越小。

OK本期C语言小tip就到这里结束啦,欢迎各位在品论区里留言,我们下期再见!

相关推荐
小小小小王王王5 分钟前
求猪肉价格最大值
数据结构·c++·算法
岁忧29 分钟前
(LeetCode 面试经典 150 题 ) 58. 最后一个单词的长度 (字符串)
java·c++·算法·leetcode·面试·go
BIYing_Aurora37 分钟前
【IPMV】图像处理与机器视觉:Lec13 Robust Estimation with RANSAC
图像处理·人工智能·算法·计算机视觉
码农编程录2 小时前
【c/c++3】类和对象,vector容器,类继承和多态,systemd,std&boost
c++
martian6652 小时前
支持向量机(SVM)深度解析:从数学根基到工程实践
算法·机器学习·支持向量机
孟大本事要学习2 小时前
算法19天|回溯算法:理论基础、组合、组合总和Ⅲ、电话号码的字母组合
算法
??tobenewyorker3 小时前
力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
数据结构·c++·算法·leetcode
让我们一起加油好吗3 小时前
【基础算法】贪心 (二) :推公式
数据结构·数学·算法·贪心算法·洛谷
贾全3 小时前
第十章:HIL-SERL 真实机器人训练实战
人工智能·深度学习·算法·机器学习·机器人
GIS小天4 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票