C语言中灵活多变的动态内存,malloc函数 free函数 calloc函数 realloc函数

文章目录
- 🚀前言
- 🚀管理动态内存的函数
- ✈️malloc函数
- ✈️free函数
- ✈️calloc函数
- ✈️realloc函数
- 🚀在使用动态内存函数时的常见错误
- ✈️对NULL指针的解引用
- ✈️ 对动态开辟空间的越界访问
- ✈️对非动态开辟内存使用free释放
- ✈️使用free释放一块动态开辟内存的一部分
- ✈️对同一块动态内存多次释放
- ✈️动态开辟内存忘记释放(内存泄漏)
🚀前言
铁子们好啊!今天阿辉给大家讲一下C语言里面特别重要的一块知识——动态内存管理,为什么说它重要呢?相信大家在使用数组时都遇到过数字开辟空间太大或者太小的情况,这是很尴尬的因为数组空间一旦确定就难以扩大或者缩小。而今天的动态内存管理将帮我们很好的解决这一窘境。话不多说,开始咱们今天的学习吧!!!
🚀管理动态内存的函数
动态内存的管理其实也就分为两块
- 空间的开辟和扩容
- 空间的释放
而要做到以上两点,我们要引入几个重要的管理动态内存的函数
动态内存的开辟和释放都是在堆区上
✈️malloc函数
malloc函数是用来开辟空间的,如何使用呢?下面是它的声明👇
void* malloc(size_t size);
关于malloc函数的注意事项:
size表示malloc函数所开辟空间的大小,单位是字节maloc函数对于开辟空间存放何种类型的数据并不关心,返回值是void*类型,malloc开辟空间成功,则返回这块空间的起始位置的地址;若开辟空间失败,则返回空指针NULL- 给
malloc传入的参数为0时,这种行为是C语言标准未定义的,取决于编译器 - 由
malloc函数开辟的空间,里面的内容是随机的
具体使用:
int mian()
{int* p = (int*)malloc(sizeof(int) * 10);//开辟10*4个字节的空间,返回值强转为int*if (p == NULL)//判断动态内存是否开辟成功{printf("malloc 开辟空间失败\n");//开辟失败返回调试语句,就是让程序员知道哪错了return 1;//开辟失败直接返回}//对动态开辟内存的进一步使用//这玩意其实就是个数组,有了首元素地址,不就是当成数组来玩嘛for (int i = 0; i < 10; i++)//十个元素初始化成0~9{p[i] = i;//这玩意与*(p+i) = i等价,不懂得可以看阿辉之前关于指针的文章}return 0;
}
关于malloc函数开辟的空间,它是一块连续的空间,直接当成数组使用一点毛病没有,
它与数组最大的区别在于,malloc开辟的空间是在堆区上的,而数组是在栈区上的。
而堆区上申请的空间须有程序员自己手动释放(Java,Python有垃圾回收机制),否则将造成内存泄漏。其实就是你从我这拿了空间去用,不用了就还给我,别占着茅坑不拉屎,你不用别人也用不了。对于堆区申请的空间的释放,这里要引入下面这个新的函数
✈️free函数
C语言提供了一个函数free,专门用来做动态内存的释放和回收的,函数声明如下:
void free(void* ptr);
对于free函数使用时的注意事项:
- 对于传给
free的参数必须是指向动态开辟内存(也就是是堆区开辟的空间)的起始地址的指针 - 若传给
free的参数是空指针NULL,free函数则什么也不干 free只会释放传入的指针指向的空间,并不会给传入指针置空,这会很危险,空间你都还给操作系统了,你这个指针还指向那里,这个指针很野得治,所以free完,指针我们要置空
int mian()
{//开辟动态空间int* p = (int*)malloc(sizeof(int) * 10);//判断动态内存是否开辟成功if (p == NULL){printf("malloc 开辟空间失败\n");return 1;}/*对动态开辟空间的使用*///不用啦,释放空间free(p);p = NULL;return 0;
}
👆这段代码就是动态内存的使用的基本模式,先开辟空间,然后判断是否开辟成功,接着使用这块空间,最后不用了把这块空间释放掉
✈️calloc函数
C语言中还提供了calloc函数,同样是进行动态内存分配的,函数声明如下:
void* calloc(size_t num, size_t size);
calloc与malloc仅有两点不同
- 使用上
calloc函数需要两个参数,开辟空间为num个大小为size个字节的空间 calloc函数开辟的空间会把每个字节全部初始化为0
int main()
{int* p = (int*)calloc(10, sizeof(int));if (p == NULL)//判断空间是否开辟成功{printf("calloc开辟空间失败\n");return 1;}for (int i = 0; i < 10; i++)//打印动态内存中的元素{printf("%d ", p[i]);}free(p);//空间释放p = NULL;//指针置空return 0;
}
输出:
0 0 0 0 0 0 0 0 0 0 //十个0
✈️realloc函数
铁子们估计有点不买账了,说好的动态内存分配,讲了这么多也没有体现动态俩字。铁子们别急,realloc函数才是今天的重头戏
C语言提供realloc函数用来使动态内存的使用更加灵活,之前开辟的空间太大或者太小都可以灵活的调整重新分配空间大小
realloc函数的函数声明
void* realloc(void* ptr,size_t size);
realloc函数在使用时要注意下面这几点:
-
ptr是要调整的空间的起始地址,ptr得是动态内存开辟的地址,若是ptr为空指针,realloc函数将与malloc函数的实现一样 -
size是realloc函数调整大小后的内存空间大小 -
realloc函数的返回值是空间调整后的起始地址,空间开辟失败返回空指针 -
realloc函数扩容的空间里面的值并未被初始化,是随机值 -
这个函数在调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间
-
对于
realloc函数调整空间有了两种情况:-
情况一:原有空间后有足够空间

-
情况二:原有空间后无足够空间,原有空间将被释放掉,重新找一块空间

-
例子:
int main()
{int* p = (int*)malloc(5 * sizeof(int));//先用malloc申请5个整型大小的内存空间if (p == NULL)//判断是否开辟成功{printf("malloc开辟空间失败\n");return 1;}int i = 0;for (i = 0; i < 5; i++){*(p + i) = 1;//把5个整型全部初始化为1}//不够用了,要再增加5个整型int* ptr = (int*)realloc(p, 10 * sizeof(int));if (ptr == NULL){printf("realloc开辟空间失败\n");return 1;}p = ptr;//空间扩容成功将ptr的地址赋给pptr = NULL;//ptr置空for (i = 0; i < 10; i++){printf("%d ", *(p + i));}free(p);p = NULL;return 0;
}
上述,使用realloc对空间做调整时,一定要新创建一个变量来接收realloc的返回值,因为如果使用指向原空间的起始地址的指针p来接收,一旦realloc开辟空间失败,p将被赋值成NULL,将找不到原来空间造成内存泄漏
🚀在使用动态内存函数时的常见错误
✈️对NULL指针的解引用
void test()
{int* p = (int*)malloc(INT_MAX / 4);*p = 20;//如果p的值是NULL,就会有问题free(p);
}
✈️ 对动态开辟空间的越界访问
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);
}
✈️对非动态开辟内存使用free释放
void test()
{int a = 10;int *p = &a;free(p);//error——不能对非动态内存进行释放
}
✈️使用free释放一块动态开辟内存的一部分
void test()
{int *p = (int *)malloc(100);p++;free(p);//p不再指向动态内存的起始位置
}
✈️对同一块动态内存多次释放
void test()
{int *p = (int *)malloc(100);free(p);free(p);//重复释放
}
✈️动态开辟内存忘记释放(内存泄漏)
void test()
{int *p = (int *)malloc(100);if(NULL != p){*p = 20;}
}
int main()
{test();while(1);
}
对于动态开辟的内存一定要记得释放,否则将造成内存泄漏
如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!!

相关文章:
C语言中灵活多变的动态内存,malloc函数 free函数 calloc函数 realloc函数
文章目录 🚀前言🚀管理动态内存的函数✈️malloc函数✈️free函数✈️calloc函数✈️realloc函数 🚀在使用动态内存函数时的常见错误✈️对NULL指针的解引用✈️ 对动态开辟空间的越界访问✈️对非动态开辟内存使用free释放✈️使用free释放一…...
小细节处理
重载运算符:重载<运算符。 bool operator<(const Edge&s)const{return w<s.w;}...
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推荐--…...
Python正则的匹配与替换
import re 查找时的注意事项,要查找的内容左右两边打出来,用真正的字符,不要用.*?,离查找内容远一点,再用.*? a /aksj<a>哈哈哈<a><p>拉阿鲁<p>\.askjp b re.findall(<a>(.*?)<…...
解决ELement-UI懒加载三级联动数据不回显(天坑)
最老是遇到这类问题头有点大,最后也是解决了,为铁铁们总结了一下几点 一.查看数据类型是否一致 未选择下 选择下 二.处理数据时使用this.$set方法来动态地设置实例中的属性,以确保其响应式 三.绑定v-if 确保每次重新加载 四.绑定key 五.完整代码...
【数据结构和算法】找出两数组的不同
其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 哈希类算法题注意事项 2.2 方法一:哈希法 三、代码 3.1 方法一:哈希法 四…...
基于Python的B站排行榜大数据分析与可视化系统
温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本文介绍了一项基于Python的B站排行榜大数据分析与可视化系统的研究。通过网络爬虫技术,系统能够自动分析B站网址,提取大量相关文本信息并存储在系统中。通过对这些信息进行…...
MySQL一些常用命令
1、登录本地MySQL #一种是 mysql -u root -p; #(输入密码后回车)#另一种是 mysql -uroot -p123456; #(在-p后面直接带上密码)2、启动MySQL服务 net start mysql; 3、关闭MySQL服务: net stop mysql; 4、创建数据库 create database 数据库名; 5、创建数据…...
WPF 新手指引弹窗
新手指引弹窗介绍 我们在第一次使用某个软件时,通常会有一个“新手指引”教学引导。WPF实现“新手指引”非常方便,且非常有趣。接下来我们就开始制作一个简单的”新手指引”(代码简单易懂,便于移植),引用到我们的项目中又可添加一…...
py注册登录界面
代码分析 引入tkinter库,并从中导入messagebox模块。 read_users()函数用于读取存储用户信息的文本文件"users.txt"。它打开文件并逐行读取,将每行的用户名和密码以空格分隔后存储在一个列表中,最后返回该列表。 login(username,…...
基于电商场景的高并发RocketMQ实战-Consumer端队列负载均衡分配机制、并发消费以及消费进度提交
🌈🌈🌈🌈🌈🌈🌈🌈 【11来了】文章导读地址:点击查看文章导读! 🍁🍁🍁🍁🍁🍁dz…...
【Java开发岗面试】八股文—数据库MySQLRedis
声明: 背景:本人为24届双非硕校招生,已经完整经历了一次秋招,拿到了三个offer。本专题旨在分享自己的一些Java开发岗面试经验(主要是校招),包括我自己总结的八股文、算法、项目介绍、HR面和面试…...
IntelliJ IDEA [设置] 隐藏 .idea 等 .XXX 文件夹
文章目录 1. 问题描述2. 解决办法3. 最后效果4. 特殊处理(正常不需要此步骤)总结 我们使用 IntelliJ IDEA 导入项目的时候,经常会看到一些 .XXX 的文件夹(例如:.idea,.mvn,.gradle 等࿰…...
每日一题——LeetCode961
方法一 排序法: 2*n长度的数组里面有一个元素重复了n次,那么将数组排序,求出排序后数组的中间值(因为长度是偶数,没有刚好的中间值,默认求的中间值是偏左边的那个)那么共有三种情况:…...
基于Unity Editor开发一个技能编辑器可能涉及到的内容
基于Unity Editor开发一个技能编辑器,涉及到的方面较多,涵盖了Unity自身的GUI框架、序列化系统、自定义编辑器、脚本调用与数据存储等。下面是几个关键点和你可能会用到的类以及API: 自定义Inspector: 使用Editor类来重写组件的I…...
Ubuntu 22.04 安装ftp实现与windows文件互传
Ubuntu 22.04 安装ftp实现与windows文件互传 1、配置安装 安装: sudo apt install vsftpd -y使能开机自启: sudo systemctl enable vsftpd 启动: sudo systemctl start vsftpd创建ftp工作目录: sudo mkdir -p /home/ftp/uftp…...
EasyPoi使用案例
EasyPoi使用案例 easypoi旨在简化Excel和Word的操作。基于注解的导入导出,修改注解就可以修改Excel;支持常用的样式自定义;基于map可以灵活定义表头字段;支持一对多的导入导出;支持模板的导出;支持HTML/Exc…...
分布式系统架构设计之分布式数据存储的分类和组合策略
在现下科技发展迅猛的背景下,分布式系统已经成为许多大规模应用和服务的基础架构。分布式架构的设计不仅仅是一项技术挑战,更是对数据存储、管理和处理能力的严峻考验。随着云原生、大数据、人工智能等技术的崛起,分布式系统对于数据的高效存…...
javaEE -18(11000字 JavaScript入门 - 3)
一:事件 (高级) 1.1 注册事件(绑定事件) 给元素添加事件,称为注册事件或者绑定事件,注册事件有两种方式:传统方式和方法监听注册方式 传统注册方式 : 利用 on 开头的…...
LangChain.js 实战系列:入门介绍
📝 LangChain.js 是一个快速开发大模型应用的框架,它提供了一系列强大的功能和工具,使得开发者能够更加高效地构建复杂的应用程序。LangChain.js 实战系列文章将介绍在实际项目中使用 LangChain.js 时的一些方法和技巧。 LangChain.js 是一个…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
