【C语言】常见的动态内存错误

C语言动态内存分配详解(malloc/calloc/free/realloc)以及常见错误 当我们在计算机上打开一个程序,或者创建一个文件时,计算机需要为其分配一定的内存空间来存储程序代码和数据。内存分配是指计算机系统将可用的内存空间分配给不同的程序或文件,以让它们能够在计算机上运行或存储。内存分配是计算机操作系统中的一项重要工作,它涉及到内存的申请、分配、使用和释放等一系列操作。不同的程序或文件需要的内存空间大小不同,因此内存分配需要按需分配,以充分利用计算机的内存资源。 阅读详情

在上篇文章中我们了解了内存操作函数,不难发现使用内存操作函数中很容易发生错误,所以本篇博客我们就来看看C语言中使用动态内存函数中经常出现的错误,从而在以后写代码过程中避免出现这些错误。

目录

一、常见的动态内存错误

1.1对NULL指针进行解引用操作

1.2对非动态开辟的内存使用free释放

1.3对动态开辟的空间的越界访问

1.4使用free释放一块动态开辟内存的一部分

1.5对一块动态内存多次释放

1.6动态开辟内存忘记释放(内存泄漏)

二、经典笔试题

题目1

题目2

题目3

三、总结


一、常见的动态内存错误

1.1对NULL指针进行解引用操作

void test()
{
    int*p=(int*)malloc(INT_MAX/4);
    *p=20;
    free(p);
}

这道题目中,我们没有对malloc开辟的空间进行判定为空,如果maloc返回的是NULL指针,则对NULL指针解引用就会产生BUG。


1.2对非动态开辟的内存使用free释放

void test()
{
    int a=10;
    int *p=&a;
    ……
    free(p);
}

这种写法当然是错误的,编译器便会报出错误。


1.3对动态开辟的空间的越界访问

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);
}

这道题中我们进行了越界访问,当i的值为10时,对p+i进行解引用就导致访问了未开辟的空间,程序必然会出现错误。


1.4使用free释放一块动态开辟内存的一部分

void test()
{
    int *p=(int*)malloc(100);
    p++;
    free(p);    //此时p不再指向动态内存的起始位置。
}

如果要释放,必须释放一块动态开辟空间的起始位置, 只释放一块空间是无法做到的。运行时程序会崩溃。


1.5对一块动态内存多次释放

void test()
{
    int*p=(int *)malloc(100);
    free(p);
    free(p);    //重复释放
} 

这样处理必然会引起程序崩溃。


1.6动态开辟内存忘记释放(内存泄漏)

void test()
{
    int *p=(int*)malloc(100);
    if(NULL != p)
    {
        *p=20;
    }
}

int main ()
{
    test();
    while(1);
}

在test函数中申请了100个整形的空间,直到test函数调用完都没有释放,随着test的销毁,这就会导致p指向的这块空间再也无法释放了,就会导致内存泄漏的问题。

切记: 动态开辟的空间一定要释放,并且正确释放。

二、经典笔试题

题目1:

void GetMemory(char* p)
{
    p =(char*)malloc(100);
}

void Test(void)
{
    char* str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}

错误原因:

1.str传参后仍为空指针。

        函数传参,传的是临时拷贝,这里我们将str传入GetMemory函数中,GetMemory函数创建了一个形式参数p来接受str指针里的值,p为一份临时拷贝,p也是一个空指针。虽然p申请道了100个字节的空间,但是没有让str指向这块空间。

2.未对p申请的空间进行释放,内存泄漏。

        p申请了空间,但是没有free。

3.strcpy参数为空指针。

        因为GetMemory函数并没有改变str,所以str仍为空指针,这就导致strcpy出错,无法拷贝,printf自然也无法执行,程序最终奔溃。

输出结果:

(什么结果都没有,没有打印出来)

解决方案:

将指针str的地址传入GetMemory,使用二级指针p接收,再对p进行解引用就可以找到str的地址,再申请100个字节的空间,这样就可以使str指向申请的空间了,然后使用完后再进行释放。

void GteMemory(char **p)      //因为传入的是指针的地址,所以要使用二级指针接受
{
    *p=(char)malloc(100);    //对p进行接引用,就可以找到str的地址
}

void Test (void)
{
    char *str =NULL;
    GetMemory( &str );         //将str的地址传入GetMemory。
    strcpy(str,"hello world");
    printf(str);
    free(str);               //str指向着申请的空间,使用后释放即可
}

题目2:

char *GetMemory(void)
{
    char p[]="hello world";
    return p;
}

void Test(void)
{
    char *str = NULL;
    str= GetMemory();
    printf(str);
}

错误原因:

1.非法访问内存。

        因为函数调用结束,数组中的内容已被销毁,p返回来的地址赋给str使str指向数组首元素的地址,但是数组p中的内容已经被销毁,str即成了野指针。

打印结果:

 


题目3:

void Test(void)
{
    char *str=(char*)malloc(100);
    strcpy(str,"hello");
    free(str);
    if(str!=NULL)
    {
        strcpy(str,"world");
        printf (str);
    }
}

先看打印结果:

错误原因:

1.空间被释放了还使用。

        这里str指向的空间已经被释放,str已经是一个野指针了,但是这里仍然将world拷贝到str指向的位置,虽然程序运行成功,并且输出了world,但是这个段代码就是一段有问题的代码。

三、总结

如何避免动态内存错误:

1.malloc开辟空间后对malloc的返回值进行判空,检查开辟空间是否失败。

2.使用动态开辟的空间时,对内存边界进行检查,避免越界访问。

3.使用完动态开辟的内存后一定要及时释放,并且要从动态内存的起始地址开始释放,不能多次释放,只有动态开辟的空间才能使用free释放。

4.释放完空间后,一定要及时将指针置为空,要不然会指针仍指向那块地址,极易发生非法访问的错误。

本篇文章就介绍到这了,希望能对大家有所帮助,看到最后留个赞呗~~

我们下期再见

论文理解【LLM-OR】——【OptMATH】A Scalable Bidirectional Data Synthesis Framework for Optimization Modeling 本文提出 LLM-OR 领域的双向数据合成框架 OptMATH,从已有 MF/PD 出发反向生成 NL,再使用 AutoFormulator 进行正向建模,通过最优值匹配 rejection sampling 确保语义一致性。实现了难度可控的语义一致数据合成 阅读详情

相关推荐

pytorch-cifar100学习资料汇总 - 基于PyTorch的CIFAR-100图像分类实践

pytorch-cifar100是一个基于PyTorch实现CIFAR-100数据集图像分类的开源项目。该项目实现了多种经典的深度学习网络模型,如ResNet、DenseNet、VGG等,为开发者提供了在CIFAR-100数据集上进行图像分类实验的代码范例。pytorch-cifar100项目为我们提供了在CIFAR-100数据集上进行图像分类实验的完整代码实现。无论你是想要学习PyTorch的使用,还是研究不同网络模型在CIFAR-100上的表现,这个项目都是一个很好的起点。

helloaiworld的博客 1123

动态内存中常见的错误

上一期我们讲到动态内存申请函数的使用,今天我们就讲一下动态内存中常见的错误 动态内存的使用一定要细心,否则的话一下就会出现错误。 而这种错误一般编译器不会报错,他们只会在运行时出错 1就是空指针解引用操作 这时候p是一个指向NULL的一个指针,下面我们给他解引用,复制给3,然后我们运行他 我们可以看到他直接崩掉了 2.对动态开辟的内存越界访问 我们可以看到,我们开辟了10和整形空间,然后我们给这10个整形空间复制但是最后我们访问20个整形空间,那么 那么就会出错,所以我们

m0_73455775的博客 226

从零到一:Qt与PCL的跨平台开发环境搭建全攻略

本文详细介绍了从零开始搭建Qt与PCL跨平台开发环境的完整流程,涵盖Windows、Linux和macOS三大平台。重点解析了Qt5与Qt6版本选择、PCL库安装配置、VTK集成等关键技术要点,并提供跨平台CMake项目模板和常见问题解决方案,助力开发者快速构建三维点云处理应用。

weixin_29280657的博客 384

常见的动态内存错误总结

七大动态内存易错点整理,陷阱避坑指南

wyd_333的博客 1081

EMC辐射发射测试:垂直与水平极化测试原理与实战指南

电磁兼容(EMC)测试是确保电子设备在复杂电磁环境中稳定运行的关键环节,其核心在于评估设备产生的电磁干扰(EMI)强度。辐射发射测试作为EMC测试的重要组成部分,通过测量设备向空间辐射的电磁噪声,判断其是否符合国际标准限值。测试原理基于电磁波的极化特性,即电场矢量的振动方向,主要分为垂直极化和水平极化。理解极化特性对于精准定位辐射源、高效进行EMC整改具有重要技术价值。在工程实践中,垂直极化噪声通常源于线缆辐射等垂直结构,而水平极化噪声多来自PCB走线等水平结构。通过分别测量两种极化方向的辐射最大值,可以全

weixin_32770423的博客 357

Android HCE实战:手把手教你用Kotlin实现NFC公交卡模拟(含完整APDU指令解析)

本文是一份Android HCE实战指南,详细讲解如何使用Kotlin实现NFC公交卡模拟。内容涵盖HCE服务搭建、APDU指令(如SELECT AID、GET PROCESSING OPTIONS)的完整解析与响应逻辑,并提供读卡器端测试代码,帮助开发者深入理解基于主机的卡模拟技术。

qsc901234567的博客 1117

malloc和strcpy,入门的指针面试题

不管是面试还是工作,在做linux应用时,是经常遇到的。结合例子简单介绍锁和条件变量。

不断debug,优化中…… 766

JMeter脚本录制-快速上手篇

有的项目应用场景下,压测时,需要考虑带宽因素,压测不只是压测接口,静态资源也要一起压测。一般来说,静态资源比较多,如果一个个手工去写请求,是比较繁琐的,此时,可以使用Jmeter的脚本录制功能。 步骤1,创建脚本录制模版。 JMeter菜单:文件>模版,下拉选择到Recording,点击“Create”按钮; 填写录制参数: hostToRecord:填写要录制的主机域名,例如,我们这里填入:www.baidu.com schemeToRecord:填写要录制的模式,例如,htt...

软件测试大叔 5734

C生万物 | 常见的六种动态内存错误

本文重点介绍C语言中的6种常见动态内存错误,带你规避致命错误

做技术人 · 产优质博客 · 找好工作 1417

三、Crowd与JIRA、Confluence用户集成并SSO单点登录

补充说明: 通过此方法集成后,用户、组以及用户和组的关系都在Crowd系统中存储,但各个系统的权限仍由各系统控制,也可在JIRA和Confluence中添加和删除用户。 在做步骤4和步骤5的时候,要特别小心,确保当前系统的超级权限用户(一般为admin,具体看当前系统的全局权限配置)和组以及它们的关系已经在Crowd中同样存在了,才可切换并禁用当前系统的内部用户目录,否则可能造成权限丢失等严重问题(因为禁用了内部用户目录,而Crowd中又不存在这个超级权限用户和组或它们的关系,所以权限就丢失了) 维护示例

weixin_38621072的博客 2985

手机开发实战58——小区广播介绍2

业务 针对小区广播短消息的特点,可以提供一些基于目前短消息不能或不适合提供的服务: 1. 显示网络服务基站名称:用户可以随时了解手机登记在哪个基站下,特别是在边界交叉覆盖区域,用户可以清楚的知道通话建立在哪个基站下,在用户投诉和故障描述中也会有所帮助; 2. 提供用户问候信息:可以在覆盖机场、车站等地区的基站广播一些用户问候语或一些企业形象广告语; 3. 充分利用小区广播地

xjbclz的专栏 772

手撕大厂出现的过的一些笔试题---------动态内存函数题

第一题: //问:下面test函数会输出什么 #Include<stdio.h> #include<stdlib.h> 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(); }

weixin_60719453的博客 1575

Android功耗系列专题分析之四:待机概率性功耗高的失效分析

本文分析了Android设备待机功耗异常高的问题。通过日志发现系统休眠失败,原因是PowerManagerService.Display唤醒锁未被释放。进一步排查发现,指纹解锁功能在灭屏时未正确释放屏幕锁定,导致DisplayReady状态异常。解决方案是将指纹功能的背光控制与DisplayReady状态控制分离,使用两个变量独立管理。经验表明,快速定位问题比解决问题更重要,修改原生流程时需谨慎评估风险。

451

【C语言】_常见动态内存错误

关于动态内存,已介绍4个动态内存管理函数,详见下文:【C语言】_4个动态内存管理函数-优快云博客本文列举常见的动态内存错误;

m0_63299495的博客 1245

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

2301_80886847的博客 621

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【C语言】常见的动态内存管理错误

上一篇介绍了C语言中,本片讲解的是 在我们使用动态内存管理时 常见的错误,一起来看看吧~如有错误,欢迎指出~

2301_80898480的博客 1254

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C语言——动态内存分配常见的错误案例

动态内存分配常见的几种错误案例

weixin_69283129的博客 1300

【C语言】动态内存的常见错误

在上章节中讲解了动态内存的概念和管理的核心函数。在本章节继续为大家介绍动态内存的常见错误,让大家更好的理解运用。补充:使用内存函数需要头文件<stdlib.h>malloccallocrealloc正确的做法是先检查返回值是否为NULL,避免直接使用指针。

2501_90303633的博客 513

C语言动态内存管理的六大常见错误

C语言动态内存管理的六大常见错误

m0_70322372的博客 545

【C语言】动态内存管理及其常见错误

我们已经掌握的内存开辟方式有://在栈空间上开辟四个字节//在栈空间上开辟10个字节的连续空间空间开辟大小是固定的。数组在申明的时候,必须指定数组的长度,数组空间一旦确定了大小不能调整。但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了C语言引入了动态内存开辟,让程序员自己可以申请和释放空间,就比较灵活了。

2301_77954967的博客 1383

c语言-常见的动态内存错误

本篇文章叙述使用c语言提供的库函数实现动态内存管理的过程中,出现常见的错误。

pyc68的博客 569

c语言之动态内存管理及常见错误分析,柔性数组,内存划分

对于c语言的动态内存管理是在原先定义数组时,数组的大小被指定,无法修改,可能造成空间的浪费或者空间不够造成越界访问,所以在此基础上提出用malloc,calloc,realloc,free四大函数来维护,自己开辟想要的空间大小,并自己释放,而柔性数组也是用来动态开辟空间的

Miwll的博客 1312

C语言常见的动态内存错误

以上操作,如果开辟空间失败p得到空指针,下面代码就会对空指针解引用。

weixin_51339619的博客 296

C语言作业:常见的动态内存错误

题目描述:注意题目描述:问的是不正确。答案:A解析:B:使用动态内存分配函数后,要对指针用free进行释放,同时将释放后的野指针置空,但是这里没有将malloc后的指针p进行释放,会出现内存泄露的问题这里C语言中是值传递,传递的是str的副本(一个NULL值),在这个函数中对副本p进行修改并不会影响主函数中str,主函数中str仍旧为NULL,因此在strcpy中向str写入字符串会出现程序崩溃。函数确实无法将malloc分配的内存地址"带回来"给调用者。

2401_88251472的博客 777

[C语言]常见的动态内存错误

忘记释放不再使用的动态开辟的空间会造成内存泄漏。动态开辟的空间一定要释放,并且正确释放。

2303_77060768的博客 234

C语言中动态内存开辟及使用的常见错误

对空指针(NULL)的解引用操作、对动态开辟空间的越界访问、使用free函数释放所开辟动态空间的一部分、用函数free对同一块动态空间多次释放、动态开辟内存忘记释放(内存泄漏)

m0_70811813的博客 523
上一篇: 【C语言】动态内存管理
下一篇: 【C语言】10分钟学会文件操作
Brant_zero2022
博客等级 码龄5年 582粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brant_zero2022

素材免费分享不求打赏,只求关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值