【c语言】【visual studio】动态内存管理,malloc,calloc,realloc详解。

引言:随着大一期末的到来,想必许多学生都学到内存的动态管理这一部分了,看望这篇博客后,希望能解除你心中对这一章节的疑惑。

(・∀・(・∀・(・∀・*)

fcd86daf76774b47ba0f81a14548685a.png

1.malloc详解

malloc的头文件是#include <sdtlib.h>,malloc - C++ Reference (cplusplus.com)

我们可以点进看看的malloc的详细内容

3cd425feee5846778cd6204de797177d.png

可以看到malloc返回值是void*类型,也就是说明在使用时我们还需要根据需要开辟空间的类型,强制类型转换成自己所要的类型。例如我们要开辟40个字节的空间,代码如下。

#include <stdlib.h>
int main()
{int* pa =(int *) malloc(10 * sizeof(int));return 0;
}

用数组的来写,如下

同样也可以实现空间的开辟,这里我们就来谈谈相同点与不同点。

#include <stdio.h>
int main()
{int pa[10];return 0;
}

相同点:

  1. 向内存申请一块空间
  2. 在程序结束时释放

不同点:

  1. 申请的内存位置不同,malloc在堆区,数组在栈区。
  2. 头文件不同,malloc头文件是<stdlib.h>,数组头文件是<stdio.h>
  3. 空间动态性,malloc所申请的空间是可变的,动态的可以通过使用realloc(下面会再讲解realloc的用法)来改变大小,数组所申请的空间是不可变的,定义完后就固定了。
  4. 数组定义时可以初始化空间内容,malloc申请空间时不能初始化内容,且其空间里的内容是随机值。
  5. malloc申请空间可能失败,数组不会。

如何理解这些不同点以及如何配套使用malloc我们看下面这一段代码

#include <stdlib.h>
int main()
{int* pa =(int *)malloc(10 * sizeof(int));if (pa == NULL){perror("malloc:");return 1;}int i = 0;for (i = 0; i < 10; i++){*(pa+i) = i;printf("%d ", *(pa+i));}free(pa);pa = NULL;return 0;
}

我们可以看到,用malloc申请完空间后,我们接着写了一段代码判断pa是否为NULL

fb0cc24487d9448289e0ac175d8333be.png

我们接上不同点5,malloc申请空间可能会失败。所以我们要分类讨论malloc申请空间的情况

1.失败返回NULL(空指针)。

2.成功返回申请到空间的首地址。

至于perror是一种打印申请空间失败原因的库函数,我们可写可不写,为了可读性最好加上,接着如果失败我们return 1结束程序。因为以及申请失败了,下面的代码是针对成功的情况,如果不结束程序,代码就会出错。

 9bb6ee7f7f094c9dbd5a88e62f78cb24.png

for循环将0到9输入到这片空间中,并打印到屏幕中,

最后使用完了这块空间,我们free释放掉(free是编译器里的库函数,用来释放某一块空间的),还回去。释放完后free函数并不会将pa置为NULL,为了防止野指针的出现,我们需要手动设为NULL.

778302513ac743838f3e96d42e4f4baf.png

2.calloc详解

calloc和malloc很类似也是申请一块空间,我们接着看。

calloc的头文件是#include <sdtlib.h>calloc - C++ Reference (cplusplus.com)

我们可以点进看看的calloc的详细内容

f46de5c5d65f49d69189099f1fb19707.png

同样我们可以看到calloc的返回值是void*,但calloc函数比malloc多了一个参数。我们具体分析

194835d2bdfc40aa9afec011b6981671.png

具体了解calloc。我们比较calloc与malloc

相同点:

1.都是向堆区申请一块空间。

2.都是动态的,可变的。

3.成功返回这块空间的首地址,失败返回NULL。

4.函数返回值都是void*。

不同点:

1.申请的空间成功时可以初始化为0,而malloc不可以。

至于不同点,我们看代码

​
​
#include <stdlib.h>
int main()
{int* pa =(int *)calloc(10 , sizeof(int));if (pa == NULL){perror("calloc:");return 1;}int i = 0;for (i = 0; i < 10; i++){printf("%d ", *(pa+i));}free(pa);pa = NULL;return 0;
}​​

我们没有给calloc申请的空间赋值,我们看结果是

14578fd50b9b4057a61f63056bca345e.png

申请空间后初始化为0。

3.realloc详解

realloc的头文件是#include <sdtlib.h>realloc - C++ Reference (cplusplus.com)

我们可以点进看看的calloc的详细内容

a37387374e5144e3803092551cdd7b8f.png

看功能,realloc是来调整malloc/calooc申请的空间。与数组的不同就体现在这。

具体分析realloc的两个参数:

ad2be7e231fa40058d6c6673b3be2dea.png

具体我们看代码操作:
 

​
#include <stdlib.h>
int main()
{int* pa = (int*)malloc(5 * sizeof(int));if (pa == NULL){perror("mallco:");return -1;}for (int i = 0; i < 5; i++){*(pa + i) = i;//pa需要+i指向下一个位置。printf("%d ", *(pa + i));}int* pb = (int*)realloc(pa, 10 * sizeof(int));if (pb == NULL){pb = pa;free(pb);pb = NULL;perror("realloc:");return 1;}elsepa = pb;for (int i = 5; i < 10; i++){*(pa + i) = i;//pa需要+i指向下一个位置。printf("%d ", *(pa + i));}free(pa);pa = NULL;return 0;
}​

代码上半部分用malloc申请一块空间后,我们觉得20字节大小不够,我们就使用realloc函数增大空间至40个字节大小。同样申请完后我们要判断申请是否成功。

bf37312dedff44bb9c164f4c8c725450.png

这里realloc比较复杂。我们一一述说:
1.失败返回NULL。

2.成功有分为两种情况

  1. 在申请时太大占用了其它已经占用空间时realloc会在内存的堆区重新找一个满足条件的空间,同时把旧的数据copy到新的空间,接着释放旧空间,同时返回新空间的起始地址。
  2. 在申请时空间够用时,返回起始地址。

所以如果pb==NULL时申请失败,我们需要把之前malloc申请的空间释放掉。并置为NULL。

总结:malloc,calloc,realloc三者都是void*类型函数,接收返回值时都要强制类型转换。在堆上申请的空间要即使释放,并置为空指针。每次申请完后要判断申请是否成功等等。

以上希望能够帮到你,让你对动态内存管理有跟深的理解。

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

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

相关文章

【C语言】——认识指针变量和地址,以及指针变量类型的意义

&#x1f3a5; 岁月失语唯石能言的个人主页 &#x1f525;个人栏专&#xff1a;秒懂C语言 ⭐若在许我少年时&#xff0c;一两黄金一两风 目录 前言 一、指针变量和地址 1.1 取地址操作符&#xff08;&&#xff09; 1.2 指针变量和解引用操作符&#xff…

Linux上使用HTTP协议进行数据获取的实战示例

嗨&#xff0c;Linux爱好者们&#xff0c;今天我们要一起探讨一下如何在Linux上进行HTTP协议的数据获取。这不是一项简单的任务&#xff0c;但放心&#xff0c;我会以最简单的语言&#xff0c;结合实例来给大家讲解。 首先&#xff0c;我们需要一个工具&#xff0c;那就是curl…

初识Dubbo学习,一文掌握Dubbo基础知识文集(2)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

springMVC-@RequestMapping

基本介绍 RequestMapping注解可以指定控制器/处理器的某个方法的请求的url, 示例 &#xff08;结合springMVC基本原理理解&#xff09; Controller public class UserHandler {RequestMapping(value "/login")public String login() {System.out.println("登…

springCloud项目打包如何把jar放到指定目录下

springCloud项目打包如何把jar发放到指定目录下 maven-antrun-plugin springCloud微服务打包jar&#xff0c;模块过多&#xff1b;我的项目模块结构如下&#xff1a; 我把实体类相关的单独抽离一个模块在service-api下服务单独写在service某块下&#xff0c; 每个模块的jar都…

如何使用jQuery获取当前网址路径

如何使用jQuery获取当前网址路径概述在前端开发中&#xff0c;经常需要获取当前网址的路径&#xff0c;通过使用jQuery库&#xff0c;我们可以轻松地实现这个功能。本文将逐步介绍如何使用jQuery获取当前网址路径。流程步骤以下是实现该功能的步骤&#xff1a;步骤 描述…

人工智能导论复习资料

题型 1、简答题&#xff08;5题&#xff09; 2、设计题 3、综合题 4、论述题&#xff08;10分&#xff09; 考点 第一章 1、人工智能的定义、发展&#xff1b; 2、人工智能的学派、认知观及其间的关系&#xff1b; 3、人工智能要素及系统分类&#xff1b; 4、人工智能的研究、…

Python轴承故障诊断 (七)基于EMD-CNN-LSTM的故障分类

目录 前言 1 经验模态分解EMD的Python示例 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 2.3 故障数据的EMD分解可视化 2.4 故障数据的EMD分解预处理 3 基于EMD-CNN-LSTM的轴承故障诊断分类 3.1 训练数据、测试数据分组&#xff0c;数据分batch 3.…

canal环境部署

docker 部署canal同步数据 1 环境: 2 Mysql 配置 查看 binlog 是否启用 SHOW VARIABLES LIKE ‘%log_bin%’; 开启 binlog, 修改 my.cnf docker cp mysql:/etc/my.cnf /data/mysql/conf 拷贝文件到临时目录修改后再拷贝回去 # For advice on how to change settings please …

【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火

​ &#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《网络安全之道 | 数字征程》⏰墨香寄清辞&#xff1a;千里传信如电光&#xff0c;密码奥妙似仙方。 挑战黑暗剑拔弩张&#xff0c;网络战场誓守长。 ​ 目录 &#x1f608;1. 初识…

渗透实验基础教程(完整版):

#江南的江 #每日鸡汤&#xff1a;影响我们人生的绝不仅仅是环境&#xff0c;其实是心态在控制个人的行动和思想。同时&#xff0c;心态也决定了一个人的视野事业和成就&#xff0c;甚至一生。 #初心和目标&#xff1a;成为网络安全达人。。。 渗透实验基础教程&#xff08;完整…

自动驾驶技术:驶向未来的智能之路

导言 自动驾驶技术正引领着汽车产业向着更安全、高效、智能的未来演进。本文将深入研究自动驾驶技术的核心原理、关键技术、应用场景以及对交通、社会的深远影响。 1. 简介 自动驾驶技术是基于先进传感器、计算机视觉、机器学习等技术的创新&#xff0c;旨在实现汽车在不需要人…

关于后端返回给我们的对象或者数组为空时我们把空字符(“”)串变成横杠(“-”)

根据需求&#xff0c;我们分别把他写成两种方法&#xff0c;在我们项目中可以 直接调用该方法&#xff0c;方法如下&#xff1a; 1.把数组中为空的项替换成横杠 //把数组中为空的项替换成横杠 export function filtrateData(data) { data.forEach(obj > { Object.keys(obj)…

WEB 3D技术 简述React Hook/Class 组件中使用three.js方式

之前 已经讲过了 用vue结合three.js进行开发 那么 自然是少不了react 我们 还是先创建一个文件夹 终端执行 npm init vitelatest输入一下项目名称 然后技术选择 react 也不太清楚大家的基础 那就选择最简单的js 然后 我们就创建完成了 然后 我们用编辑器打开创建好的项目目…

Angular中使用Intersection Observer API实现无限滚动

背景&#xff1a; 实现原理为 在data下面加一个loading元素 如果此元素进入视窗 则调用api获取新的数据加到原来的数据里面&#xff0c;这时loading就会被新数据顶下去&#xff0c;如此循环。 <div id"dataContainer"></div> <div id"loadingCo…

Win7系统桌面出现白色透明框的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

高云GW1NSR-4C开发板M3核RT-Thread应用

1.仅提供RT-Thread的Nano版本 MCU工程在\EMPU(GW1NS-4C)_V1.2\ref_design\MCU_RefDesign\Keil_RefDesign\rt_thread_nano\PROJECT目录下&#xff0c;FPGA工程参考&#xff1a; 高云GW1NSR-4C开发板M3硬核应用-CSDN博客 特别注意&#xff0c;MCU主频&#xff08;即FPGA工程经P…

Adaptive IBC :异构链互操作性的颠覆者

2024年第一季度&#xff0c;隐私协议 Secret Network 将会使用 Octopus Network 基于 Adaptive IBC 技术路线开发的 NEAR IBC&#xff0c;实现与 NEAR Protocol 之间将会实现首次跨链交互&#xff0c;这同样是 Cosmos 生态与 NEAR 之间的首次连接。整个加密世界正在成为一个越来…

【lesson14】MySQL表的基本查询retrieve(读取)1

文章目录 表的基本操作介绍retrieveselect列建表基本测试 where子句建表基本测试 表的基本操作介绍 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; retrieve select列 建表 基本测试 插入数据 全列查询 …

深度学习记录--矩阵维数

如何识别矩阵的维数 如下图 矩阵的行列数容易在前向和后向传播过程中弄错&#xff0c;故写这篇文章来提醒易错点 顺便起到日后查表改错的作用 本文仅作本人查询参考(摘自吴恩达深度学习笔记)