动态内存管理详细讲解
目录
1.为什么存在动态内存分配
2. 动态内存函数的介绍
2.1 malloc和free
2.2 calloc
2.3 realloc
今天要和大家分享的内容是的动态内存管理,我们先从他的定义入手学习。
1.为什么存在动态内存分配
我们到现在已经掌握了内存开辟的方式就是要么创建一个变量,要么就创建一个数组
int a = 0;char arr[10] = { 0 };
如上所示,创建一个变量,就是在栈空间上开辟四个字节;创建一个char类型的数组里面有十个元素,就是在栈空间上开辟10个字节的连续的空间;
那我们目前学到的开辟空间的方法只有这两种方法;
这两种方法创建的空间大小是固定的,int类型就是四个字节,char类型的数组就是十个字节,不能将其增大也不能减小。所以这种方式在某些环境下是有一定的局限性的,所以为了让我们能更加灵活的控制我们所需要的内存的空间的大小,这时我们就需要学习C语言中动态内存管理的功能,
也会涉及到其中的一些相关的函数,接下来就对这些函数进行分析。
2. 动态内存函数的介绍
2.1 malloc和free
先在官方的网站上大概了解一下它的内容
malloc本质上是一个函数,使用时要包含<stdlib.h>的头文件,返回类型是人任意类型的指针,参数是 size_t类型,也就是无符号整形, 他的作用是在内存中申请数个字节的内存块,返回一个指针指向这个内存块的起始位置。
上代码简单使用一下这个函数
int main()
{int* p =(int*) malloc(20);return 0;
}
那么这段代码什么意思呢?
假设我们要开辟二十个字节的空间,我们就在malloc后面的括号中输入想要开辟的空间,注意单位是字节;
再来观察一下malloc函数的返回值,是一个任意类型的指针,我们在使用时要将其具体细化成我们想要的数据,那这里我们举一个例子,不妨将其定义为整形指针,所以也要给malloc函数开辟的空间的类型强制转化成int类型(我们所要使用的类型)
那以上就是malloc开辟空间的简单使用。
接下来在深度研究之前要了解一些知识
上图是我们计算机内存划分的简单的示意图,这里要为大家说明的是我们所创建的临时变量,和函数的形式参数以及具有临时性的变量都放在栈区;
我们今天索要讲解的动态内存管理的函数所申请的内存空间都在堆区中,可以看到上图有很多动态内存管理的函数,都会一一讲解;
最后就是静态区,静态区所存放的就是static所修饰的静态变量和全局变量;
了解完这些我们再回头看我们的malloc函数
我们使用malloc申请空间的时候要注意,malloc申请空间可能因为空间不足而导致申请失败,
而申请失败时就会返回一个空指针,所以我们在使用malloc函数时要对其进行判断;
代码如下
int main()
{int* p =(int*) malloc(20);if (p = NULL){printf("%s\n",strerro(errno));return 1;}
上面说过申请失败会返回一个空指针,我们不妨对其进行判断 :
如果p是空指针的话,就打印出他错误的原因,打印分析出错的原因后就利用return 1结束当前的程序,因为已经申请空间失败了,不能再往下走了,相信大家不难看懂
使用malloc函数申请空间后,要使用free来释放空间,
那free是怎样释放空间的呢?
可以看到free的函数的参数是一个任意类型的指针,也就是说使用free释放空间的时候,只需要将malloc申请的空间的首地址传进free函数中即可。
所以上面的代码中,malloc申请空间的首地址赋值给了指针变量p,所以我们将p传入free中即可
接下来将代码调试起来
可以看到malloc开辟的空间的首地址已经赋给了p;
这时free函数已经释放了p指针指向的空间,
但是这时我们要注意到是虽然空间已经得到了释放,但我们可以看到指针p指向了一块不知道的空间,这时p就成了一块野指针,所以我们要在最后将空指针赋予p
这时我们就看到p已经忘记了当时申请的20个字节的空间在哪
这时候就避免了野指针的问题;
申请空间和释放空间都研究过后我们再来看一看如何使用这块空间;
使用也非常的简单,既然我们申请的时一块连续的空间,我们不妨用数组来将其应用:
对申请的二十个空间进行访问我们可以利用数组的遍历对其访问,并将其打印出来以便我们观察
可以看到使用其申请的空间没有那么困难。
2.2 calloc
可以看到calloc函数的返回值是一个任意类型的指针,函数的两个参数都是size_t类型的数。
下面的对函数功能的描述是说开辟并且用'0'初始化数组。
用代码简单使用calloc函数:
int main()
{int* p = (int*)calloc(10, sizeof(int));if (p == NULL){printf("calloc()--%s", strerror(errno));return 1;}//使用int i = 0;for (i = 0; i < 10; i++){printf("%d ", *(p + i));}//释放free(p);p = NULL;return 0;}
可以看到使用对其开辟的空间时只是将其打印出来
运行的结果就是将其开辟的内容全都初始化为0;
那calloc和malloc有何区别呢?
1.参数不同
malloc只有一个参数,要开辟多少字节的空间直接在后面的括号内告诉他就好;
calloc有两个参数,要确定多少和一个数据多大的参数,类似于数组的开辟方式;
2.两者都是在堆区上申请空间,但是malloc不初始化,calloc会初始化为0;
如果要初始化就选择calloc,不需要初始化就选择malloc,具体要看需求使用 。
malloc在返回地址之前没有初始化,而calloc在返回地址之前要全部初始化为0,所以calloc的效率是比malloc要低的
2.3 realloc
继续观察官方网站对这个函数的定义
它的返回类型是任意类型的指针,函数的一个参数是任意类型的指针,另一个数size_t的无符号整型的整数;
对函数功能的描述就是改变内存块的大小
realloc函数的作用就是 让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时
候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小
的调整
我们直接用代码简单探究一下
我们可以看到这里再使用空间中增加了realloc的使用,这个意思就是说在指针p指向的首地址处,向后开辟40个字节的空间(注意这里开辟空间的字节大小要是加上之前空间的总大小)
使用这段空间也有两种方法,下面为大家用图例演示会更加便于理解
第一种情况:
这种增加内存的情况是在原先的内存空间中续上一段内存(篮筐表示realloc函数续上的内存)。这种情况下是因为本身申请的空间不会受到别的内存的干扰。
第二种情况:
上图这种情况时我们发现原本的空间后面,已经没有我们能够所再申请加长的空间了,这时候realloc就会重新申请一块更大的空间空间在别的地方,同时它会将之前空间的内容拷贝到新的空间中,这块空间一定满足你所开辟的空间,同时也会释放旧的空间,然后返回新空间的地址。
这就是realloc函数使用时内部会发生的情况;
但是要注意的是两种情况放回的地址不一样,第一种情况会返回旧的地址,第二种情况会返回新的地址。当然还要想到的一种情况可能会返回空指针,万一realloc在申请空间失败的情况下就会返回空指针,这点也必须考虑到,所以我们必须要用一个临时指针来存放他申请的空间,并且加以判断
使用例子如下
int*ptr=(int*)realloc(p, 40);if (ptr!=NULL){p = ptr;}else{printf("%s\n",strerror(errno));return 1;}
先使用realloc函数开辟空间,并将其首地址存入一个临时的指针变量,并加以判断,如果不是空指针,就交给原先的p指针对这块空间进行管理。
如果真的开辟空间失败的话,就结束当前进程。
那接下来就给大家调试起来,让大家看看是否真的会存放在不同的空间
我们可以看到两个指针的指向的地址是同样的,
那怎么样才会不一样呢?
我们只需要将realloc申请的空间增大
就可以看到两者的地址已经不一样了,这就是realloc在申请空间时的第二种情况。
以上就是索要分享的动态内存管理的函数的要分享的内容,下次会给大家分享常见的动态内存的错误。
如果这篇文章对你有所帮助,也请三连多多支持一下,感谢阅读。
相关文章:
![](https://img-blog.csdnimg.cn/6b68a3c1ecf745c5abba18af6d499b53.png)
动态内存管理详细讲解
目录 1.为什么存在动态内存分配 2. 动态内存函数的介绍 2.1 malloc和free 2.2 calloc 2.3 realloc 今天要和大家分享的内容是的动态内存管理,我们先从他的定义入手学习。 1.为什么存在动态内存分配 我们到现在已经掌握了内存开辟的方式就是要么创建一个变量…...
![](https://img-blog.csdnimg.cn/9d7eafb22d70477db3d32448efee92ef.png)
Python和Excel的完美结合:常用操作汇总(案例详析)
在以前,商业分析对应的英文单词是Business Analysis,大家用的分析工具是Excel,后来数据量大了,Excel应付不过来了(Excel最大支持行数为1048576行),人们开始转向python和R这样的分析工具了&#…...
![](https://img-blog.csdnimg.cn/01fba945bac4402087db1146f400a0bc.png)
卡特兰数、斯特林数基础
卡特兰数 从格点(0,0)(0,0)(0,0)走到格点(n,n)(n,n)(n,n),只能向右或向上走,不能穿过对角线,的路径的条数,称为卡特兰数HnH_nHn。 则有H01H_01H01。 通项公式: Hn(2nn)−(2nn−1)H_n\begin{pmatrix} 2n\\ n \en…...
STL——mapmultimap和setmultiset
一、关联式容器 与序列式容器相同,关联式容器也是用于存储数据的,不同的是,关联式容器里存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。 二、键值对 用来表示具有一一对应的一种结构,该…...
![](https://img-blog.csdnimg.cn/4a204d9e7d524b94a3513d1f53e696d1.jpeg)
2023热门抖音权重查询小程序源码
2023热门抖音权重查询小程序源码 跟抖音上很火的一模一样,小程序适配优化。接口免费。小程序不是网页 修改教程: 1,如果想修改或者去除水印,直接删除或修改“index.html”12~22行 2,如果想修改logo,直接…...
![](https://img-blog.csdnimg.cn/5800422d3c3e44b8915a2525ec7b1edc.png)
153.网络安全渗透测试—[Cobalt Strike系列]—[生成hta/exe/宏后门]
我认为,无论是学习安全还是从事安全的人多多少少都会有些许的情怀和使命感!!! 文章目录一、后门简介1、hta后门2、exe后门3、宏病毒后门二、生成后门并测试0、测试环境1、生成hta后门并测试2、生成exe后门并测试3、生成宏病毒后门…...
![](https://img-blog.csdnimg.cn/41a3a632482c4e3fbb3025669252d0e6.png)
如何成为优秀的程序员
崔宝秋,现任小米首席架构师、小米云平台负责人。1995年赴美留学,纽约州立大学石溪分校计算机科学系博士毕业,曾任IBM高级工程师和高级研发经理、雅虎搜索技术核心团队主任工程师、LinkedIn主任工程师,2012年回国加入小米科技。 20…...
![](https://img-blog.csdnimg.cn/970dc100d8cf496e84d50d43aa66638c.png)
多线程(四):线程安全
在开始讲解线程安全之前我们先来回顾一下我们学了那些东西了: 1. 线程和进程的认识 2. Thread 类的基本用法 3. 简单认识线程状态 4. 初见线程安全 上一章结束时看了一眼线程安全问题,本章将针对这个重点讲解。 一个代码在单线程中能够安全执行&am…...
![](https://img-blog.csdnimg.cn/bab327e98da44a5d9f771d59909d698d.png)
[ROC-RK3568-PC] [Firefly-Android] 10min带你了解Camera的使用
🍇 博主主页: 【Systemcall小酒屋】🍇 博主追寻:热衷于用简单的案例讲述复杂的技术,“假传万卷书,真传一案例”,这是林群院士说过的一句话,另外“成就是最好的老师”,技术…...
![](https://www.ngui.cc/images/no-images.jpg)
C++之模拟实现string
文章目录前言一、包含的相关头文件二、构造和析构1.构造函数2.拷贝构造1.传统写法2.现代写法3.赋值运算符重载1.传统写法2.现代写法4.析构函数三、iterator四、modify1.push_back(尾插一个字符)2.append(尾插一个字符串)3.运算符重载1.尾插字…...
![](https://img-blog.csdnimg.cn/14e618ffdda240b099774c7c013d5634.png)
SpringBoot实战(十三)集成 Admin
目录一、简介二、搭建 springboot-admin 管理服务1.Maven 依赖2.application.yml3.添加 EnableAdminServer4.启动服务,查看页面三、搭建 springboot-admin-client 客户端服务1.Maven 依赖2.application.yml3.启动服务,查看页面四、搭配 Eureka 使用1.搭建…...
![](https://www.ngui.cc/images/no-images.jpg)
mke2fs命令:建立ext2文件系统
以下内容源于网络资源的学习与整理,如有侵权请告知删除。 使用格式 mke2fs [options] [设备名称] [区块数] options与含义 -c:检查是否有损坏的区块。-F:不管指定的设备为何,强制执行mke2fs。-M:记录最后一次挂入的…...
![](https://img-blog.csdnimg.cn/5a3ef2ba0cd24ec7b32bf3b3df18d1c2.png)
免费分享一个springboot+vue的办公系统
springbootvue的OA系统项目介绍项目部署项目特点项目展示项目介绍 这是一个采用前后端分离开发的项目,前端采用 Vue 开发、后端采用 SpringBoot Mybatis 开发。 很适合java初学者练手和学习。 前端技术:Vue3.2 Vue-Router Pinia Ant Design Vue 3.X…...
![](https://img-blog.csdnimg.cn/a0d9514957b642258e38fba10d96a3b6.png)
STM32数据搬运工DMA
DMA的概念DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路ÿ…...
![](https://img-blog.csdnimg.cn/a30d8aec94f74a9480193d9bee7ebac5.png)
4、操作系统——进程间通信(2)(system V-IPC介绍)
目录 一、system V-IPC常识 1、key和ID 2、文件描述符 3、函数(ftok) ftok产生IPC对象的健值key(类似文件路径) 4、例子 5、使用命令查看或删除当前系统中的IPC对象 一、system V-IPC常识 1、key和ID (1&#x…...
![](https://img-blog.csdnimg.cn/8c3b5ebfa3c24999ae01fe4290946403.png)
基于CentOS Stream 9平台搭建Nacos2.0.4集群以及OpenResty反向代理
目录展示Nacos2.0.4集群搭建1. 下载2. 解压3.修改配置3.1分别修改下启动类中JDK路径以及启动大小3.2 分别配置数据源3.3 创建nacos数据库3.4 修改cluster.conf配置3.4.1 复制并修改3.4.2 编辑文件,修改三台主机地址3.4.3 分别放入另外两个nacos的conf目录下:4. 启动…...
![](https://www.ngui.cc/images/no-images.jpg)
老杜MySQL入门基础 第二天
导入演示数据 1、连接MySQL 2、创建"bjpowernode"数据库 create database bjpowernode;3、选择数据库 use bjpowernode4、导入数据 source D:\bjpowernode.sql(文件的路径)1 去除重复记录(把查询结果去除重复记录)(原表数据不会改变) 使用关键字dist…...
![](https://img-blog.csdnimg.cn/f60d13d125b54d67806e29d37da37d77.png)
Python深度学习实战:人脸关键点(15点)检测pytorch实现
引言 人脸关键点检测即对人类面部若干个点位置进行检测,可以通过这些点的变化来实现许多功能,该技术可以应用到很多领域,例如捕捉人脸的关键点,然后驱动动画人物做相同的面部表情;识别人脸的面部表情,让机…...
![](https://img-blog.csdnimg.cn/1fd7d99c7ef24aa3858ab41be9e34987.png)
linux简单入门
目录Linux简介Linux目录结构Linux文件命令文件处理命令文件查看命令常用文件查看命令Linux的用户和组介绍Linux权限管理Linux简介 Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯本纳第克特托瓦兹࿰…...
![](https://img-blog.csdnimg.cn/img_convert/3fd41b48bbc631605622485d88988d6d.png)
给准备面试网络工程师岗位的应届生一些建议
你听完这个故事,应该会有所收获。最近有一个23届毕业的大学生和我聊天,他现在网络工程专业大四,因为今年6、7月份的时候毕业,所以现在面临找工作的问题。不管是现在找一份实习工作,还是毕业后找一份正式工作࿰…...
![](https://img-blog.csdnimg.cn/img_convert/7a1065f025d18ca2e980fe272a59de45.jpeg)
主线程与子线程之间相互通信(HandlerThread)
平时,我们一般都是在子线程中向主线程发送消息(要在主线程更新UI),从而完成请求的处理。那么如果需要主线程来向子线程发送消息,希望子线程来完成什么任务。该怎么做?这就是这篇文章将要讨论的内容。 一、…...
![](https://img-blog.csdnimg.cn/778840fa1b57415185083096a9e62cde.png)
13基于双层优化的电动汽车日前-实时两阶段市场竞标
MATLAB代码:基于双层优化的电动汽车日前-实时两阶段市场竞标 关键词:日前-实时市场竞标 电动汽车 双层优化 编程语言:MATLAB平台 参考文献:考虑电动汽车可调度潜力的充电站两阶段市场投标策略_詹祥澎 内容简介:…...
![](https://img-blog.csdnimg.cn/f08402187b874a409e691b0501183074.png)
REDIS19_zipList压缩列表详解、快递列表 - QuickList、跳表 - SkipList
文章目录①. 压缩列表 - zipList②. 快递列表 - QuickList③. 跳表 - SkipList①. 压缩列表 - zipList ①. ZipList是一种特殊的"双端链表",由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作,并且该操作的时间复杂度为O(1) (oxff:11111111) type…...
![](https://www.ngui.cc/images/no-images.jpg)
JavaScript 基础 - 第3天
文章目录JavaScript 基础 - 第3天笔记数组数组的基本使用定义数组和数组单元数据单元值类型数组长度属性操作数组JavaScript 基础 - 第3天笔记 数组 数组的基本使用 定义数组和数组单元 <script>// 1. 语法,使用 [] 来定义一个空数组// 定义一个空数组let…...
![](https://img-blog.csdnimg.cn/cd43e71cfa7745849c1164aedab377c7.png)
23.3.26总结
康托展开 是一个全排列与自然数的映射关系,康托展开的实质是计算当前序列在所有从小到大的全排列中的顺序,跟其逆序数有关。 例如:对于 1,2,3,4,5 来说,它的康托展开值为 0*4!0*3!0*2!0*1&…...
![](https://www.ngui.cc/images/no-images.jpg)
【Java学习笔记】37.Java 网络编程
Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。 java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题&…...
![](https://img-blog.csdnimg.cn/1773631be592441bbb63fee65cc0f8d4.png)
Azure OpenAI 官方指南03|DALL-E 的图像生成功能与安全过滤机制
2021年1月,OpenAI 推出 DALL-E。这是 GPT 模型在图像生成方面的人工智能应用。其名称来源于著名画家、艺术家萨尔瓦多 • 达利(Dal)和机器人总动员(Wall-E)。DALL-E 图像生成器,能够直接根据文本描述生成多…...
![](https://img-blog.csdnimg.cn/img_convert/41b3b816f5f110d88a98a378f6357cba.gif)
【数据结构】堆
文章目录前言堆的概念及结构堆初始化堆的判空堆的销毁插入数据删除数据堆的数据个数获取堆顶数据用数组创建堆对数组堆排序有关topk问题整体代码展示写在最后前言 🚩前面了解了树(-> 传送门 <-)的概念后,本章带大家来实现一…...
![](https://img-blog.csdnimg.cn/img_convert/a3ef3c9302415847405b310f8b56dd8c.webp?x-oss-process=image/format,png)
电脑硬盘文件数据误删除/格式化为什么可以恢复? 怎么恢复?谈谈文件删除与恢复背后的原理
Hello 大家好, 我是元存储~ 主页:元存储的博客_CSDN博客 1. 硬盘数据丢失场景 我们在每天办公还是记录数据的时候,文件存储大多数都是通过硬盘进行存储的,因此,使用多了,各种问题就会出现,比如…...
![](https://img-blog.csdnimg.cn/img_convert/e654eb7a1a8d429bae8f4668d477f459.png)
Gateway服务网关
Spring Cloud Gateway为微服务架构提供一种简单有效的统一的 API 路由管理方式。Gateway网关是所有微服务的统一入口。网关的核心功能特性:请求路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则&am…...
![](/images/no-images.jpg)
wordpress高亮代码/seo内部优化具体做什么
自定义的DataSet要加 [Serializable]标记。...
![](/images/no-images.jpg)
用什么软件建手机网站/品牌推广活动有哪些
早晨起床时间:6:10 晚上休息时间:23:16 全天处理事件:1.整理论文以及答辩记录表文档,并提交。2.开始下一个学习目标。 处事经验总结:暂无。 人生感悟:暂无。 其它:暂无。...
wordpress写插件/网络营销最基本的应用方式是什么
前言 开门见山,开篇明意。这篇博客主要讲解一下Android中ProgressBar控件以及间接继承它的两个子控件SeekBar、RatingBar的基本用法,因为其有继承关系,存在一些共有特性,所以在一篇博客中讲解。下面先简单描述一下这三个控件&…...
![](/images/no-images.jpg)
上海建站中心/网络营销专业就业公司
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一…...
![](https://img-blog.csdnimg.cn/20200130193951864.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ1MTYxNzY2,size_16,color_FFFFFF,t_70)
做那个网站的小编比较好/域名查询系统
利用代码来记录当前时间值或求某步操作所用时间值,本例以执行图片像素改变为例! 代码如下: import cv2 as cv #导入openc包 import numpy as np #科学计数的包def access_pixels(image): #获取图片像素的函数print(image.shap…...
![](/images/no-images.jpg)
linux主机 安装wordpress/深圳网络营销策划公司
同步自:http://www.blogjava.net/AndersLin/archive/2006/06/27/55421.html 上次发了一文《软件企业的绩效管理和内部消耗》讨论很多,"置身珠海,学习与奋斗"cnBlogs让我认识其实我说了那么多都只是绩效的保健性&…...