【C语言进阶篇】常见动态内存分配的这六个错误你必须避免!

news2024/11/26 0:43:04

在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》

⛺️生活的理想,就是为了理想的生活!

文章目录

  • 前言
  • 💬 常见的动态内存错误
    • 1️⃣ 对NULL指针的解引用操作
      • ⌨️ 错误原因
      • 💻 解决方法:
    • 2️⃣ 对动态开辟空间的越界访问
      • ⌨️ 错误原因
      • 💻 解决方法:
    • 3️⃣ 对非动态开辟内存使用free释放
      • ⌨️ 错误原因
    • 4️⃣ 使用free释放一块动态开辟内存的一部分
      • ⌨️ 错误原因
    • 5️⃣ 对同一块动态内存多次释放
      • ⌨️ 错误原因
      • 💻 解决方法:
    • 6️⃣ 动态开辟内存忘记释放(内存泄漏)
      • ⌨️ 错误原因
      • 💻 内存泄漏危害:
      • 总结

前言

  🌈hello! 各位宝子们大家好啊,前面一章给大家带来了动态内存分配的四个函数的讲解!malloc free calloc realloc 这四个库函数不知道大家还记得吗?
  ⛳️动态内存分配学完了那么,这些关于内存分配的错误你就必须避免了!
  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

🔥 注:上一章学习内容是《动态内存分配》

💬 常见的动态内存错误

1️⃣ 对NULL指针的解引用操作

📚 代码演示:

void test()
{
	int* p = (int*)malloc(INT_MAX / 4);
	*p = 20;//如果p的值是NULL,就会有问题
	free(p);
}

⌨️ 错误原因

⛳️ 这里我们对malloc的返回值用p接收,然后解引用进行赋值错误点在:

  • malloc 我们上一篇我们说了它的返回值有可能是空指针
  • 而我们对空指针进行解引用,会导致导致程序异常终止或拒绝服务
  • 所以这种肯定是错误的,所以一定要进行判断在进行接收

在这里插入图片描述

💻 解决方法:

void test()
{
	int* p = (int*)malloc(INT_MAX / 4);
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}
	*p = 20;//如果p的值是NULL,就会有问题
	free(p);
}

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

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int i = 0;
	int* p = (int*)malloc(10 * sizeof(int));
	if (NULL == p)
	{
		perror("malloc");
			return 1;
	}
	for (i = 0; i < 11; i++)
	{
		p[i] = i;//当i是10的时候越界访问
	}
	free(p);
	return 0;
}

⌨️ 错误原因

⛳️不知道大家看出来了没有,我们这里总共就申请了10个整形的空间。而调用的时候缺想访问11个整形进行赋值.

  • 这不就造成了越界访问,只申请了10个整形大小
  • 你却想用11个整形大小,谁给你的胆子 ⁉️😄
  • 这样就会照成程序的崩溃,所以一定要避免

📑 代码结果:
在这里插入图片描述

💻 解决方法:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int i = 0;
	int* p = (int*)malloc(10 * sizeof(int));
	if (NULL == p)
	{
		perror("malloc");
			return 1;
	}
	for (i = 0; i < 10; i++)
	{
		p[i] = i;//当i是10的时候越界访问
	}
	free(p);
	return 0;
}

📌 所以解决办法也非常简单只要,我们避免就可以啦!

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

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int a = 10;
	int* p = &a;
	free(p);//ok?
	return 0;
}

⌨️ 错误原因

⛳️free这个函数只能释放我们动态内存开辟的空间,结果你非要去栈区上释放空间

  • 这种代码一般是我们喝醉了才会这样用😂😂😂
  • 开个玩笑哈!
  • 注:关于free函数和栈区我们在动态函数时有详细讲解!《动态内存详细讲解》

📑 代码结果:

在这里插入图片描述

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

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int* p = (int*)malloc(100);
	p++;
	free(p);//p不再指向动态内存的起始位置
	return 0;
}

⌨️ 错误原因

这种情况是释放了对于属于我们开辟的内存空间,没有释放完全

  • 当我们把p指针偏移之后,就不在指向原来的起始位置
  • 所以当我们对p指向的空间进行释放的时候就会进行 内存泄漏
  • 这是非常严重的编程错误,直接会导致程序崩溃
    在这里插入图片描述

📑 代码结果:
在这里插入图片描述

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

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int* p = (int*)malloc(100);
	free(p);
	free(p);//重复释放
	return 0;
}

⌨️ 错误原因

  ⛳️ 这也是写代码糊涂了才会这样,对一块内存进行多块释放!本来p的地址我们都已经释放完了你还让我释放一遍这怎么能这样呢?

📑 代码结果:
在这里插入图片描述

💻 解决方法:

这个解决方法也非常简单,我们只要每次 free 释放完把 p 置为空指针就可以了。

  • p 里面都是空指针,都没有存地址
  • 那么我们不管怎么释放都没问题了
    在这里插入图片描述

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

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
void test()
{
	int* p = (int*)malloc(100);
	if (NULL != p)
	{
		*p = 20;
	}
}
int main()
{
	test();
	while (1);
	return 0;
}
;

⌨️ 错误原因

  ⛳️ 这个情况就有点像我们看的侦查片里面的卧底,我们派了 小王 进行卧底但是只有警员 阿SIR 记得小王的档案为了保密其他人都不知道,有一天 阿SIR 突然去世了,这时不就没人记得 小王的卧底身份了!

  • 这里我们test进行了申请空间但是没有进行释放
  • 而出了这个函数 p 也就进行销毁了没人记得这
  • 个开辟空间的地址

💻 内存泄漏危害:

  ⛳️那么内存泄漏有什么危害呢?这个其实很常见 内存病毒 不知道大家听说过没有?每次开机都没问题,但总是用不到多长时间就会死机!

  • 这个是不是就和内存泄漏很像,如果我们
  • 写了一个程序每次都申请空间都不释放
  • 那么时间长了这个程序就会直接崩溃! ⁉️

所以一定要避免这种情况,免得以后费力吧唧的写了一个代码人家说什么鬼程序用一下就崩!
🔥 注:动态开辟的空间一定要释放,并且正确释放 。

总结

✅ 归纳:
好了以上就是关于动态内存分配的全部注意事项就全部讲解完毕啦!
  对NULL指针的解引用操作
  对动态开辟空间的越界访问
  对非动态开辟内存使用free释放
  使用free释放一块动态开辟内存的一部分
  对同一块动态内存多次释放
☁️ 好了这些就是常见动态内存分配的错误了,大家一定要避免啊!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

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

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

相关文章

MonoDTR Monocular 3D Object Detection with Depth-Aware Transformer 论文学习

论文链接&#xff1a;MonoDTR: Monocular 3D Object Detection with Depth-Aware Transformer 1. 解决了什么问题&#xff1f; 单目 3D 目标检测对于自动驾驶很重要&#xff0c;也很有挑战性。 现有的一些方法通过深度预测网络得到深度信息&#xff0c;然后辅助 3D 检测&…

总结930

之前本打算每天学12h&#xff0c;践行了一周&#xff0c;一天最多也就学11.5h,在时间利用上感觉已经趋于饱和的了。 这个时候&#xff0c;时间统计法应该能发挥它应有的作用了&#xff0c;但就算详细记录每日时间支出&#xff0c;也不能从根本上解决问题。 一味的进行时间上的…

学习记录——语义分割、实时分割和全景分割的区别、几个Norm的区别

语义分割、实时分割和全景分割区别&#xff1f; semantic segmentation&#xff08;语义分割&#xff09; 通常意义上的目标分割指的就是语义分割&#xff0c;图像语义分割&#xff0c;简而言之就是对一张图片上的所有像素点进行分类。   语义分割&#xff08;下图左&#…

护网实训场景二-

首先攻击者入侵到了web服务器&#xff0c;构建一个socks5代理&#xff0c;去入侵办公区&#xff0c;通过办公区在构建二层代理去拿下核心区就这么一个流程。 攻击&#xff1a;先开始扫描 防御&#xff1a;导入流量包&#xff0c;在分析平台去看告警 这就是一个很明显的目录扫描…

Linux 部署Vue+Spring Boot项目

部署Vue Spring Boot项目 安装redis wget http://download.redis.io/releases/redis-4.0.8.tar.gz tar -zxvf redis-4.0.8.tar.gz yum install gcc-c make make install如果出现下面的问题&#xff1a; yum install tcl make testredis-server myconifg/redis.conf输入客户端…

Vue 安装 Vue-router 路由安装以及使用

vue-router 是 Vue 的一个插件库&#xff0c;适用于构建单页面应用。 单页面应用&#xff1a;整个应用中只有一个完整的页面&#xff0c;切换页面就是替换页面中的内容。 工作原理&#xff1a;当浏览器的路径发生改变时&#xff0c;路由器会自动显示路径所对应的组件。 嵌套…

【主轴线】不规则多边形主轴线计算与显示

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 不规则多边形的主轴线 计算方法与显示方法 1. 正文 主轴线的计算与显示 首先&#xff0c;我们计算多边形的中心点&#xff0c;然后将顶点坐标相对于中…

经典文献阅读之--DAMS-LIO(基于iEKF的轻量级LiDAR惯性里程计)

0. 简介 融合方案是多传感器融合方法的关键&#xff0c;多传感器融合方法是地下矿山和行星表面等复杂极端环境下状态估计的最有前途的解决方案。本文提出了一种基于iEKF的轻量级LiDAR惯性里程计系统&#xff0c;该系统采用可感知退化的模块化传感器融合管道&#xff0c;仅在检…

C语言小项目——通讯录高阶(文件管理版)

通讯录初阶: 点这里 通讯录中阶: 点这里 文件管理版本改进之处通讯录初始化退出通讯录并保存 完整代码contact.hcontact.ctest.c 文件管理版本改进之处 通讯录初始化 contact.c 退出通讯录并保存 test.c contact.c contact.h 完整代码 contact.h #pragma once#include&l…

缕析条分Scroll属性 | 京东云技术团队

最近有项目需要使用js原生开发滑动组件&#xff0c;频繁要用到dom元素的各种属性&#xff0c;其中以各种类型的height和top属性居多&#xff0c;名字相近&#xff0c;含义也很容易搞混。因此特地总结归纳了一下常用的知识点&#xff0c;在文末我们来挑战实现一个简易的移动端Sc…

Window下编译ffmpeg

Window下编译ffmpeg 下载MSYS2编译ffmpeg运行 下载MSYS2 MSYS2是一个是工具和库的集合&#xff0c;它能够方便的在windows上编译、安装和运行程序。ffmpeg可以通过这个软件来编译。 从MSYS2官网下载MSYS2并安装。 运行MSYS2终端&#xff0c;在终端中输入命令&#xff0c;安装…

JVM运行时数据区——Java虚拟机栈

每个线程在运行时都会创建一个Java虚拟机栈&#xff0c;也是线程私有的&#xff0c;其内部包含一个个的栈帧&#xff0c;先进后出&#xff0c;对应着一个个方法的调用&#xff0c;运行完则弹出&#xff0c;所以不存在垃圾回收的问题&#xff0c;如果线程所需要的栈深度大于此线…

什么是芯片组,南桥与北桥芯片的作用与区别

主板是连接计算机所有部件的PCB。在老式计算机中&#xff0c;所有芯片都分布在主板上。在现代计算机中&#xff0c;芯片数量减少并集中在特定位置。因此&#xff0c;将多个芯片组合起来形成一个芯片。这种可以替代大量芯片的芯片称为芯片组。主板上有一个芯片组。芯片组处理CPU…

docker在linux下简单部署项目

springboot项目docke部署 1.手动部署 1. 编写dockerfile文件 2. 将jar包和docker文件放到服务器上 执行mvn clean package docker:build 3.执行docker images查询是否存在镜像 4.启动方式放在下面写 2.通过gitlab ci/cd方式实现自动化部署 3.创建一个.gitlab-ci.yml 文件 3…

匿名内部类/Lambda Java和Kotlin谁会导致内存泄漏?

前言 内存泄漏是程序界永恒的话题&#xff0c;对于Android开发来说尤为重要&#xff0c;想让你的App表现得更优雅&#xff0c;了解并治理内存泄漏问题势在必行。 通过本篇文章&#xff0c;你将了解到&#xff1a; 何为内存泄漏?Android 常见内存泄漏场景Java匿名内部类会导致…

Vue3警告提示(Alert)

可自定义设置以下属性&#xff1a; 警告提示内容&#xff08;message&#xff09;&#xff0c;类型&#xff1a;string | slot&#xff0c;默认&#xff1a;‘’警告提示的辅助性文字介绍&#xff08;description&#xff09;&#xff0c;类型&#xff1a;string | slot&#…

14 - 堆栈 - 小顶堆

前面我们学习了线性结构的栈, 今天我们来学习一种非线性结构-堆 堆的定义 堆是一种非线性结构,可以把堆看作一棵二叉树, 堆的存储可以使用数组来存放! 堆的分类 堆可以分为大顶堆和小顶堆。 大顶堆: 每个结点的值都大于或等于其左右孩子结点的值。 小顶堆: 每个结点的值…

目标检测——yolo系列算法

目录 yolo算法yolo算法思想yolo的网络结构网络输入网络输出7x7网格30维向量 yolo模型的训练训练样本的构建损失函数模型训练 模型预测yolo总结 yoloV2预测更准确(better)batch normalization使用高分辨率图像微调分类模型采样Anchor Boxes聚类提取anchor尺度边框位置的预测细粒…

设计模式之单例模式的实现形式、弊端以及可替代的解决方案。

你好&#xff0c;我是爱养猫的程序员雪球&#xff0c;今天与你分享设计模式之单例模式。 单例模式是指一个类只允许创建一个对象&#xff08;或实例&#xff09;的模式。它在很多应用场景中具有重要作用&#xff0c;例如处理资源访问冲突&#xff08;如日志文件写入&#xff09…

生信分析案例 Python简明教程 | 视频12

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…