【C语言进阶(八)】动态内存管理

news2024/12/25 0:20:54

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多C语言知识
  🔝🔝


在这里插入图片描述


动态内存规划

  • 1. 前言
  • 2. 为什么要学动态内存管理?
  • 3. 动态内存管理函数介绍
  • 4. malloc函数详细介绍
  • 5. free函数详细介绍
  • 6. calloc函数详细介绍
  • 7. realloc函数详细介绍
  • 8. 总结以及拓展

1. 前言

本章目标:

本篇文章
着重讲解动态内存
管理的四个函数

前期准备:

内存可以大致分为几个区域:

  • 栈区: 存放局部变量,函数
  • 堆区: 存放动态开辟的空间
  • 静态区 : 全局变量,static修饰变量
  • 代码区: 常量字符串

今天的主角就是在堆区申请空间的:
动态内存管理!

在这里插入图片描述


2. 为什么要学动态内存管理?

我们平常使用数组时:

int arr[6]={1,2,3,4,5,6};

这是在栈区开辟的空间
并且它的大小是固定的,被初始化成6

原因一:

很多情况下,我们需要的空间大小
在程序运行后才知道,此时数组不管用了
只能尝试使用动态内存管理的方式了
!

原因二:

在做题时经常遇见需要手动动态
开辟空间的题目,且在笔试中也经常考察

在这里插入图片描述


3. 动态内存管理函数介绍

动态内存管理有四个函数:

1. malloc
2. calloc
3. realloc
4. free

这些函数定义在头文件: stdlib.h中

前两个是用于开辟空间的
realloc是用于扩容的
而free是释放空间的


4. malloc函数详细介绍

先看它在cplusplus上的定义:

在这里插入图片描述

我直接把要点翻译过来:

  • 功能:它向内存申请一块连续可用的空间
  • 申请空间成功就返回指向这块空间的指针
  • 申请空间失败就返回空指针NULL
  • 返回类型是void*
    它可以申请任一类型的空间

  • 参数size的单位是字节
    开辟size个字节的空间

需要注意的地方:

  1. 它的返回类型是void*,你在开辟空间时
    应强制类型转换成你要开辟的空间的类型
struct S
{
  int a;
  char cc;
  double d;
};

int* p = (int*)malloc(40);
char* arr = (char*)malloc(10);
struct S* ss = (struct S*)malloc(20);

总结:开辟什么类型的空间就强转成什么


  1. malloc有可能申请空间失败
    所以每次开辟空间后要判断指针是否为空
    若指针为空应该直接终止掉程序
int* p = (int*)malloc(40);
if(p == NULL)
{
	printf("动态申请失败");
	exit(-1)//退出程序
}
else //不为空再去使用它
{
	//......
}

总结:每次开辟空间后要判断空指针


5. free函数详细介绍

先看free在官网上的定义:

在这里插入图片描述

将要点翻译过来:

  • free用于释放动态开辟的空间
  • 参数ptr指向的空间必须是动态开辟的
  • 若ptr是空指针,则free函数什么都不做

需要注意的地方:

  1. free释放的空间必须在堆区
    也就是必须是动态开辟的内存
//堆区开辟的空间
int* p = (int*)malloc(40);
//栈区开辟的空间
int arr[4] = {1,2,3,4};
//正确的用法
free(p);
//错误的用法
free(arr);

总结:free释放的空间必须在堆区


  1. 被free释放后的空间就还给操作系统了
    但是指针还是指向已经释放的空间
    所以在free释放掉一块空间后
    还要将指针赋值为空才安全
int* p = (int*)malloc(40);
free(p);
p = NULL;

总结:释放掉空间后记得要置空


6. calloc函数详细介绍

先看calloc的定义:

在这里插入图片描述

重点翻译:

  • 参数num是要开辟的空间个数
  • 参数size是每份空间所占字节数
  • calloc不仅会开辟空间
    还将所有数据初始化为0

  • 它和malloc的区别就是前者会初始化

使用举例:

//开辟10个整型空间
int* p = (int*)calloc(10,sizeof(int));
if(p == NULL)
{
	printf("开辟失败");
	exit(-1);
}
else
{
	//......
}

可以在不同场景选择使用
malloc或者calloc


7. realloc函数详细介绍

先看realloc的定义:

在这里插入图片描述

重点翻译:

  • 参数ptr是指向要扩容的空间的指针
  • 参数size是扩容后空间总大小
    单位是字节
  • 返回值为扩容之后的内存起始位置
  • 此函数在调整原先空间大小的基础上
    还会将原先空间的内容拷贝过来

需要注意的地方:

  1. realloc扩容的空间必须在堆区
int* p = (int*)malloc(40);
int arr[4]={1,2,3,4};
//正确用法
int* pp = (int*)realloc(p,60);
//错误用法
int* parr = (int*)realloc(arr,30);

  1. 若参数ptr是空指针NULL
    则realloc的功能相当于malloc
int* p = NULL;
int* pp = (int*)realloc(p,40);

此时的realloc相当于malloc


  1. realloc扩容后,原先指向
    这块空间的指针会自动置空
    不需要再手动置空
int* p = (int*)malloc(40);
int* pp = (int*)realloc(p,60);

free(pp);
pp=NULL;

总结:realloc扩容后,原先的指针可以不管


8. 总结以及拓展

动态开辟的内存在堆区上
而我们定义的指针却在栈区上
所以可以这样理解这个过程:

在这里插入图片描述


🔎 下期预告:常见动态内存错误 🔍

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

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

相关文章

ElasticSearch索引(index)当中的增删改查操作

文章目录 一、创建索引(Create Index):二、更新索引的设置(Update Index Settings):三、获取当前索引的设置(Get Index Settings):四、删除索引(Delete Index…

Python(十三)数据类型——整数类型

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

N!9个OA高危漏洞利用工具v1.1.6

工具介绍 该工具使用了ExpDemo-JavaFX项目,保留了核心的数据包请求接口,使用jdk1.8环境开发。目前只编写了oa系列,对相关漏洞进行复现和分析,极力避免exp的误报和有效性。 关注【Hack分享吧】工众号,回复关键字【2305…

基于linux下的高并发服务器开发(第一章)- fcntl函数

13 / fcntl函数 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ...); 参数&#xff1a; fd : 表示需要操作的文件描述符 cmd: 表示对文件描述符进行如何操作 - F_DUPFD : 复制文件描述符,复制的是第一个参数fd&#xff0c; …

【运维工程师学习六】LAM部署搭建个人Discuz论坛

【运维工程师学习六】LAM部署搭建个人Discuz论坛 1、先卸载Mariadb再安装Mysql2、MySQL官网rpm包下载3、在rpm包路径下安装 YUM Repo 文件4、更新软件仓库本地数据库信息5、开始部署——php的安装6、搜索yum包7、开始部署——配置apache以支持php&#xff08;1&#xff09;配置…

Spring MVC 运行原理 【深度理解】

什么是MVC&#xff1f; MVC 是 Model、View 和 Controller 的缩写&#xff0c;分别代表 Web 应用程序中的 3 种职责&#xff0c;MVC是一种软件设计规范。它将业务逻辑、数据、显示分离的方法来组织代码&#xff0c;降低了视图与业务逻辑之间的双向耦合。 Model(模型)&#xf…

newMap和newSet

newMap Map 对象存有键值对&#xff0c;其中的键可以是任何数据类型。Map字典是以[键&#xff0c;值]的形式存储** 1:键值对的键类型比较灵活 可以用任意类型的变量来做键名&#xff0c; 2 遍历键值对 for … in循环还有一些限制&#xff1a;它仅仅遍历可枚举属性、非Symb…

进程概念与进程控制

1.冯诺伊曼体系结构: 数据按照二进制存储 数据存储在存储器&#xff08;内存&#xff09;当中 输入设备 存储器 中央处理器 输出设备 2.操作系统&#xff1a; 先组织&#xff0c;再描述 系统调用与库函数&#xff1a; 系统调用 系统调用指运行在用户空间的程序向操作系统内核…

小程序-----vant weapp安装以及自定义主题色

首先查看小程序根目录中是否存在package.json文件 没有的话,在项目根目录打开cmd,输入npm init -y初始化一下,初始化一个包管理 安装vant weapp包 在根目录的cmd中输入npm i vant/weapp1.3.3 -S --production进行安装 后面可以指定版本 修改 app.json 将 app.json 中的 “…

【Python】类型注解 ③ ( 使用 # type: 类型 注释方式设置类型注解 | 类型注解是提示性而非强制性 )

文章目录 一、使用 注释语法 设置 类型注解1、使用 注释语法 设置 类型注解语法介绍2、为 基础类型变量 设置 " 类型注解 "3、为 类 的 对象类型 设置 " 类型注解 "4、为 基础容器类型变量 设置 简易 " 类型注解 "5、为 基础容器类型变量 设置 详…

Node.js下载安装和环境变量配置(详细教程)

目录 一、官网地址下载安装包 二、安装程序 三、环境配置 四、测试 五、安装淘宝镜像 5.1、附加&#xff1a;如果有出现问题的小伙伴们可以检查一下自己的配置有没有出错 一、官网地址下载安装包 https://nodejs.org/zh-cn/download/ 选择你的项目或系统对应的node.js版本…

【C++】 Qt-线程并发与线程同步

文章目录 线程并发线程同步原子访问&#xff08;InterLocked&#xff09;关键段&#xff08;Critical_Section&#xff0c;也叫临界区&#xff09;回顾单例出现的问题关键段基本使用封装关键段 Qt下的多线程多线程与进度条Qt-QThread 线程并发 我们再创建一个控制台文件命名为…

【Tauri + React 实战】VCluster - 了解技术选型与开发环境配置

VCluster A React Tauri App as visualizer of apps cluster on windows. 背景介绍 VCluster是一个在开发环境下&#xff0c;用以对一系列应用集群&#xff08;如分布式、微服务&#xff09;进行可视化管理的桌面应用程序&#xff0c;目标是实现类似 docker-compose 那样的集…

深入学习Python自定义函数

目录 0. 前言1. 最基础的自定义函数写法2. 参数传递3. 函数返回值4. 作用域5. 匿名函数6. 装饰器7. 闭包8. 生成器9. 为自定义函数写注解 0. 前言 今天来深入学习 Python 中的自定义函数&#xff0c;为的是日后能够写出时间和内存更好的优化&#xff0c;以及形成良好的编程习惯…

原型链:揭开JavaScript背后的神秘面纱

文章目录 1. 对象2. 原型&#xff08;prototype&#xff09;3. 原型链&#xff08;prototype chain&#xff09;4. 构造函数&#xff08;constructor&#xff09;5. prototype 属性6. 实例&#xff08;instance&#xff09;7. 原型继承&#xff08;prototype inheritance&#…

HFSS仿真微带型威尔金森功分器学习笔记

HFSS仿真微带型威尔金森功分器 文章目录 HFSS仿真微带型威尔金森功分器1、 求解器设置2、 建模3、 边界条件设置4、 激励方式设置5、 扫频设置6、 设计检查&#xff0c;仿真分析7、 数据后处理 设计要求&#xff1a; 频带范围0.9~1.1GHz输入端口的回波损耗&#xff1e;20dB频带…

STL算法篇之拷贝修改类算法

STL算法篇之拷贝修改类算法 拷贝类算法copy与copy_backwardremove与remove_copyremove_if与remove_copy_if 修改类算法replace与replace_copyreplace_if与replace_copy_ifiter_swap与swap与swap_range、unique与unique_copy 拷贝类算法 1.copy 区间拷贝 2.copy_backward 逆向拷…

Redis双写一致性?

双写一致性&#xff1a;当修改了数据库的数据也要同时更新缓存的数据&#xff0c;缓存和数据库的数据要保持一致。 Redis作为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性&#xff09; 1.我们当时做排行榜业务时&#xff0c;把历史榜…

CentOS7中安装docker并配置阿里云加速器

文章目录 一、docker的安装二、docker的卸载三、配置加速器四、docker-compose安装五、docker-compose卸载六、docker-compose相关命令七、常用shell组合 一、docker的安装 参考&#xff1a;https://docs.docker.com/engine/install/centos 本文内容是基于&#xff1a;CentOS L…

Python 算法基础篇:大O符号表示法和常见时间复杂度分析

Python 算法基础篇&#xff1a;大 O 符号表示法和常见时间复杂度分析 引言 1. 大 O 符号表示法 a ) 大 O 符号的定义 b ) 示例代码 2. 常见时间复杂度分析总结 引言 在分析和比较算法的性能时&#xff0c;时间复杂度是一项重要的指标。而大 O 符号表示法是用来描述算法时间复杂…