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

news2024/10/6 4:05:29

前言

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

对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.coloradmin.cn/o/1718617.html

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

相关文章

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池&#xff0c;希望电池还有电芯片在工作的时候插入电源不要给芯片复位&#xff0c;当电池没电&#xff0c;芯片不在工作的时候&#xff0c;插入电源给芯片复位所以使用一个PNP三极管&#xff0c;通过芯片IO控制是否打开复位&#xff0c;当芯片正常工作的…

反激电源压敏电阻设计

压敏电阻的作用&#xff1a;浪涌防护。在电源出现浪涌冲击时&#xff0c;保护核心器件不受到损坏。其实类似于稳压二极管 瞬间的瞬态波 1 压敏电压 单位是&#xff0c;虽然压敏电阻可以吸收很大的浪涌能量&#xff0c;但是不能承受mA以上的持续电流。压敏电压计算公式 2 通流容…

(函数)字符串拼接(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <string.h>//声明字符串拼接函数&#xff1b; void splice(char a[100], char b[100]);int main() {//初始化变量值&#xff1b;char a[100] …

unity打包的WebGL部署到IIS问题

部署之后会出错&#xff0c;我遇到的有以下几种&#xff1b; 进度条卡住不动 明明已经部署到了IIS上&#xff0c;为什么浏览网页的时候还是过不去或者直接报错。 进度条卡住不动的问题其实就是wasm和data的错误。 此时在浏览器上按F12进入开发者模式查看错误&#xff08;下图…

【前端】Vuex笔记(超详细!!)

最近花了两周时间&#xff0c;完完全全的跟着Vuex官方的视频学完了Vuex并且详详细细的做了笔记&#xff0c;其中总结部分是我对于整个视频课程的总结&#xff0c;视频部分是跟着视频做的笔记&#xff0c;如果总结部分有不懂的话&#xff0c;直接去视频部分查找对应的笔记即可&a…

uniapp的tooltip功能放到表单laber

在uniapp中&#xff0c;tooltip功能通常是通过view组件的hover-class属性来实现的&#xff0c;而不是直接放在form的label上。hover-class属性可以定义当元素处于hover状态时的样式类&#xff0c;通过这个属性&#xff0c;可以实现一个类似tooltip的效果。 以下是一个简单的例…

9.Halcon3D点云力矩求解-平面拟合用法

1.实现效果 我们在使用3d相机对产品进行扫描生成点云的时候,由于安装问题,所以我们不可能保证每次产品扫描出来都在坐标系中位置和姿态非常标准。 上述算法描述的就是在某一个维度或者某几个维度上将点云数据和坐标系对齐; 至于怎么对齐,如何实现就是今天的内容。 本人能…

热电子光探测器的电磁场空间分布与FDTD材料折射率的导出

仿真实例 金属薄膜中金纳米孔阵列透射与反射&#xff0c; 并考虑其近场电磁分布 利用脚本进行电磁场及其光学响应的可视化 设置EOT型超表面结构&#xff0c;以及Structure library的使用 结构的参数化扫描与结果可视化 利用脚本计算峰值增强因子 多层平面结构激发T…

如何打造智能客服机器人的“超级大脑”?

一、引言 在数字化浪潮的推动下,智能客服机器人已成为企业服务升级、提升客户满意度的关键工具。然而,要让智能客服机器人真正发挥其在客户服务中的优势,打造其“超级大脑”至关重要。本文将深入探讨如何进一步提升智能客服机器人的智能水平,并结合其在多业务场景中面临的挑…

去掉el-table表头右侧类名是gutter,width=17px的空白区域(包括表头样式及表格奇偶行样式和表格自动滚动)

代码如下&#xff1a; <el-table:data"tableData"ref"scroll_Table":header-cell-style"getRowClass":cell-style"styleBack"height"350px"style"width: 100%"><el-table-column prop"id" l…

算法思想总结:哈希表

一、哈希表剖析 1、哈希表底层&#xff1a;通过对C的学习&#xff0c;我们知道STL中哈希表底层是用的链地址法封装的开散列。 2、哈希表作用&#xff1a;存储数据的容器&#xff0c;插入、删除、搜索的时间复杂度都是O&#xff08;1&#xff09;&#xff0c;无序。 3、什么时…

【机器学习】探索未来科技的前沿:人工智能、机器学习与大模型

文章目录 引言一、人工智能&#xff1a;从概念到现实1.1 人工智能的定义1.2 人工智能的发展历史1.3 人工智能的分类1.4 人工智能的应用 二、机器学习&#xff1a;人工智能的核心技术2.1 机器学习的定义2.2 机器学习的分类2.3 机器学习的实现原理2.4 机器学习的应用2.5 机器学习…

解锁 GPT-4o 背后数据带来的情绪价值

GPT-4o 可以说已经是一个富有情感、通人性的智能语音助手&#xff0c;或者更准确地说&#xff0c;是一个越来越接近人类交互的 “新物种”。这个强大的模型同时具备文本、图片、视频和语音理解和合成方面的能力&#xff0c;甚至可以被视为 GPT-5 的一个未完成版。 01 富有情感的…

【博客20】缤果Matlab串口调试助手V1.0(中级篇)

超级好用的Matlab串口调试助手 开发工具: MATLAB 2024a中文版 (编程语言matlab) -> Matlab APP Designer 目录 前言 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 ​ ​---- ◇♣♡♠ ---- 2.其他扩展App展示 ​编辑 三、获取 >> 源码以及G…

Android 图表开发开源库 MPAndroidChart 使用总结

1. 引言 电视项目中需要一个折线图表示节电数据变化情况&#xff0c;类比 H5 来说&#xff0c;Android 中也应该有比较成熟的控件&#xff0c;经过调研后&#xff0c;发现 MPAndroidChart 功能比较强大&#xff0c;网上也有人说可能是目前 Android 开发最好用的一个三方库了&a…

ChatGPT Edu版本来啦:支持GPT-4o、自定义GPT、数据分析等

5月31日&#xff0c;OpenAI在官网宣布&#xff0c;推出ChatGPT Edu版本。 据悉&#xff0c;这是一个专门为大学校园提供的ChatGTP&#xff0c;支持GPT-4o、网络搜索、自定义GPT、数据分析、代码生成等功能&#xff0c;可以极大提升学生、老师的学习质量和教学效率。 目前&…

算法-扫描线

目录 什么是扫描线算法&#xff1f; 扫描线简单应用 更多的扫描线 什么是扫描线算法&#xff1f; 在计算几何中&#xff0c;扫描线算法&#xff08;scan line algorithm&#xff09;一般用来解决几何图形的面积交并&#xff0c;周长交并问题&#xff0c;扫描线算法的核心思想…

AC/DC电源模块:应用于工业自动化领域

BOSHIDA AC/DC电源模块&#xff1a;应用于工业自动化领域 AC/DC电源模块是一种用来将交流电转换为直流电的电源模块。它在工业自动化领域有着广泛的应用&#xff0c;可以为各种设备和系统提供稳定可靠的电力供应。 一&#xff0c;AC/DC电源模块在工业自动化领域中起到了稳定…

洞察全球商机:精细化策略引领海外营销平台对接

随着全球市场的不断融合和互联网技术的飞速发展&#xff0c;企业越来越意识到海外营销与客服系统对接的重要性。 NetFarmer&#xff0c;作为一家专注于服务企业数字化出海的公司&#xff0c;对于海外市场的洞察和对接策略有着独特的见解。今天运营坛将深入探讨海外营销平台对接…

上市医疗巨头构建330+项自动化场景,实在Agent驱动效率与效益双重飞跃

历经二十年的快速发展&#xff0c;中国医疗信息化已迈入一个崭新阶段&#xff0c;其特征是产业链的高度集成、跨部门协同作业以及信息化的深度渗透。这一阶段不仅要求医护人员聚焦于以患者为中心的高质量服务&#xff0c;还提出了新挑战&#xff0c;即如何高效处理信息化系统伴…