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

前言

在动态内存函数的使用过程中我们可能会遇到一些错误,这里将常见的错误进行总结。

对NULL解引用

请看以下代码:

可以看到,这时我们的malloc开辟是失败的,所以返回的是空指针NULL,而我们却没有进行检查,而是直接对其解引用,最终想要打印这块内存的内容,也是失败的。

这里的下波浪线是vs给出的没有进行检查的警告,即使malloc申请的空间没有那么大可以成功申请,最终也能正常打印,这个警告依然会存在

总之,就是不要忘记检查返回值是否为NULL。

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

动态开辟的空间也有自己的大小,所以也有越界。

可以看到,此时vs很智能地给出了警告。 

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

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

这段代码中,p指向的明明不是动态开辟来的空间,却对它进行free,会发生什么呢?

可以看到会出现这样的后果。(动态内存相关的错误常见现象)

 

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

我们知道,如果用*(p+i),在访问数组的过程中,i在改变,但p始终没有改变。

int* p = (int*)malloc(10*sizeof(int));
if (p == NULL)
{perror("malloc");return 1;
}int i = 0;
for(i=0;i<5;i++)
{*(p+i)=i;
}free(p);
p=NULL;

而我们还有另一种移动指针的写法:

int* p = (int*)malloc(10*sizeof(int));
if (p == NULL)
{perror("malloc");return 1;
}int i = 0;
for(i=0;i<5;i++)
{*p=i;p++;
}free(p);
p=NULL;

在这种写法中,p自身发生了改变。当退出循环时,由于p++,此时我们的p指向的是第6个元素(数组只有5个元素)。所以我们的p现在不指向动态开辟内存的起始位置。而使用free必须是传起始地址。

所以,我们不应该让p乱动

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

如果是这样的多次释放:

free(p);
p = NULL;free(p);
p = NULL;

这倒是没什么问题,因为前面已经把p置为NULL了,而对NULL进行释放会什么都不做。

但如果是这样的多次释放,就会有问题:

free(p);free(p);
p = NULL;

因为我们并没有把p置为NULL,那么此时p成为了野指针,我们对野指针进行释放,这是有问题的。

所以又可以再次看出,将p释放后及时置为NULL的重要性。

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

这是各类问题中相当令人头疼的一个。开辟了内存,也使用了,但是忘记释放了。

比如,我们在调用free()之前写了会提前返回的代码(这是很有可能发生的):

void test()
{int flag = 1;int* p = (int*)malloc(100);if (p == NULL){return;}//假设这里使用了这块内存if (flag)//假设某个条件发生了,就提前返回return;free(p);p=NULL;
}int main()
{test();//假设这里还有很多代码return 0;
}

所以这时,我们开辟来的这块空间没有机会释放了。

而且从test回到主函数后,还有很多代码,已经找不回这块空间了,也就是内存泄漏了。

只有等到主函数彻底结束,这块空间才会回收。

内存泄漏指的是一块空间动态开辟后,使用完又不释放,也可能再没法释放,这块空间就相当于消失或者说泄漏了。

所以可以看到,即使我们的malloc和free已经成对使用了,也有可能出现无法释放的情况,这样的内存泄漏的问题必须在写代码时小心,在出问题时也得慢慢去查。

(如果想让后面的程序去释放,那就要把指针返回给后面的程序)

 内存泄漏有多可怕呢,比如一些服务器程序,24/7,一直在运行,如果内存泄漏,一会吃掉一点内存,可能就把内存耗干了,机器就挂了。

总结

动态内存是一把双刃剑,能够提供灵活的内存管理方式,同时也会带来风险。

到此,本文就结束了,祝阅读愉快^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/19729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐:4本易发表的优质SSCI期刊,含期刊官网!

01、Risk Management and Healthcare Policy 开源四区&#xff0c;国人发表占比25%&#xff0c;发表量前三的国家分别是中国、埃塞俄比亚和美国。 该期刊对国人友好&#xff0c;年度发文量400多&#xff0c;影响因子3.6。 主要刊发公共卫生相关的文章。 研究者可以围绕居民…

【C++ C#】 C++ 和C# 的混合项目,C++ 文件中有多个 函数和变量 定义了未使用,会影响程序正常执速度吗?

文章目录 1 未使用的函数和变量 是否会影响速度分析1.1 C 未使用的函数和变量&#xff1a;1.2 C# 未使用的函数和变量&#xff1a; 2 影响程序执行速度的其他因素3 如何处理未使用的代码 一个 C 和C# 的混合项目&#xff0c;C 文件中有多个 函数和变量 定义了未使用&#xff0c…

推荐系统三十六式学习笔记:01|你真的需要个性化推荐系统吗?

目录 什么是推荐系统你需要推荐系统吗总结 什么是推荐系统 让我们来换一个角度回答三个问题&#xff0c;从而重新定义什么是推荐系统: 1、它能做什么&#xff1f; 2、它需要什么&#xff1f; 3、它怎么做。 对于第一个问题“它能做什么”&#xff0c;我的回答是&#xff1a;推…

2020年CSP-J入门级第一轮初赛真题

一、选择题 在内存储器中每个存储单元都被赋予一个唯一的序号&#xff0c;称为&#xff08;&#xff09;。 A.地址 B. 序号 C. 下标 D. 编号 答案&#xff1a;A. 地址 在内存储器中&#xff0c;每个存储单元都有一个唯一的标识&#xff0c;用于区分和访问不同的存储单元。这个唯…

说说你对单例模式的理解?如何实现?

一、是什么 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;创建型模式&#xff0c;提供了一种创建对象的最佳方式&#xff0c;这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建 在应用程序运行期间&am…

day23--单元测试-反射-注解-动态代理

day23-单元测试、反射 恭喜同学们&#xff0c;Java主要的知识我们其实已经学习得差不多了。今天同学们再把单元测试、反射、注解、动态代理学习完。Java的基础知识就算全齐活了。 首先&#xff0c;我们进入单元测试的学习。 一、单元测试 1.1 单元测试快速入门 所谓单元测…

北斗消防系统实现林海无信号应急通信,高效防灾救灾开拓应急救援新通道

最近&#xff0c;贵州多地爆发的重大山火&#xff0c;火势 21日这12天里&#xff0c;贵州发生森林火情221起&#xff0c;当地包括武警、消防、专业救援队伍等在内的9千多人连续扑救&#xff0c;1.5万名基层党员干部、民兵、群众及志愿者协助救火。目前&#xff0c;贵州全省火灾…

OSPF状态机+SPF算法

OSPF状态机 1.点到点网络类型 down-->init-->(前提为可以建立邻接)exstart——>exchange-->若查看邻接的DBD 目录后发现不用进行LSA 直接进入ful。若查看后需要进行查询、应答先进入loading&#xff0c;在查询应答完后再进入 fuIl: 2.MA网络类型 down --&g…

【计算机网络】——概述(图文并茂)

概述 一.信息时代的计算机网络二.互联网概述1.网络&#xff0c;互连网&#xff0c;互联网&#xff08;因特网&#xff09;1.网络2.互连网3.互联网&#xff08;因特网&#xff09; 2.互联网简介1.互联网发展的三个阶段2.互联网服务提供者&#xff08;ISP&#xff09;3.互联网的组…

HTTP/超文本传输协议(Hypertext Transfer Protocol)及HTTP协议通信步骤介绍和请求、响应阶段详解;

目录 一、HTTP/超文本传输协议 特点和功能 请求-响应模型 版本和扩展 安全性和加密 二、HTTP协议通信步骤介绍 三、请求、响应阶段详解 HTTP请求 HTTP响应 示例 一、HTTP/超文本传输协议 HTTP/超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff09;是…

浅谈人机交互

人机交互&#xff08;Human-Computer Interaction&#xff0c;HCI&#xff09;&#xff0c;是指关于设计、评价和实现供人们使用的交互式计算机系统&#xff0c;并围绕相关的主要现象进行研究。 狭义的讲&#xff0c;人机交互技术主要是研究人与计算机之间的信息交换&#xff0…

wpf窗体背景镜像渐变效果实现

<Window.Background> <!--镜像渐变--> <RadialGradientBrush Center"0.5,0" GradientOrigin"0.5,-0.5" RadiusX"0.7" RadiusY"1.2"> <GradientStop Color"#ff61baff" Offset"0&q…

【康耐视国产案例】智能AI相机:深度解析DataMan 380大视野高速AI读码硬实力

随着读码器技术的不断更新迭代&#xff0c;大视野高速应用成为当前工业读码领域的关键发展方向。客户对大视野高速读码器的需求源于其能显著减少生产成本并提升工作效率。然而&#xff0c;大视野应用场景往往伴随着对多个条码的读取需求&#xff0c;这无疑增加了算法的处理负担…

cuda 11.6 pytorch安装

在安装之前&#xff0c;需要先配置GPU环境&#xff08;安装CUDA和CudaNN) 命令行输入nvidia-smi&#xff0c;查看驱动信息 nvidia-smi 安装相应的CUDA 和CUDANN 验证&#xff1a;输入nvcc --version 或者nvcc -V 进行检查 nvcc --version nvcc -V 在anaconda里创建环境 co…

NLP课程笔记-基于transformers的自然语言处理入门

toc 项目地址 https://github.com/datawhalechina/learn-nlp-with-transformers/ 2017年&#xff0c;Attention Is All You Need论文&#xff08;Google Brain&#xff09;首次提出了Transformer模型结构并在机器翻译任务上取得了The State of the Art(SOTA, 最好)的效果。2…

ADB安装教程

1 adb简介 Android 调试桥 (adb) 是一种功能多样的命令行工具&#xff0c;可让您与设备进行通信。 adb命令可用于执行各种设备操作&#xff0c;例如安装和调试应用。 adb 提供对 Unix shell&#xff08;可用来在设备上运行各种命令&#xff09;的访问权限。它是一种客户端-服务…

一篇文章带你弄懂Java集合的泛型

目录 第一问&#xff1a;什么是泛型&#xff1f;有什么好处&#xff1f; 第二问&#xff1a;泛型是如何实现的呢&#xff1f; 第三问&#xff1a;类型擦除的缺点有哪些&#xff1f; 第四问&#xff1a;泛型中上下界限定符extends和super有什么区别&#xff1f; 第五问&…

HR人才测评,如何做中层管理人员的素质测评?

中层管理人员是企业中的重要力量&#xff0c;他们是连接高层管理和基层员工的桥梁&#xff0c;对企业的发展至关重要。因此&#xff0c;对中层管理人员的素质测评尤为重要。下面&#xff0c;我将介绍一些HR人才测评的方法和步骤&#xff0c;以帮助企业准确评估中层管理人员的素…

中信银行积极开展2024年金融科技活动周宣传活动

近日&#xff0c;2024年全国金融“科技活动周”正式启动。中信银行围绕“弘扬科学家精神 激发全社会创新活力”为主题&#xff0c;积极面向公众宣传各类金融知识&#xff0c;全面营造热爱科学、崇尚科学的社会氛围。 自5月25日起&#xff0c;中信银行通过全国网点大屏播放宣传…

【C++】77组合

给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 使用回溯算法。我们可以按照以下步骤来实现&#xff1a; 创建一个辅助函数 backtrack&#xff0c;用来进行回溯搜索。其中包括当前组合的状态变量 current、起始…