【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.rhkb.cn/news/219005.html

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

相关文章

Spring Cloud + Vue前后端分离-第5章 单表管理功能前后端开发

Spring Cloud Vue前后端分离-第5章 单表管理功能前后端开发 完成单表的增删改查 控台单表增删改查的前后端开发&#xff0c;重点学习前后端数据交互&#xff0c;vue ajax库axios的使用等 通用组件开发:分页、确认框、提示框、等待框等 常用的公共组件:确认框、提示框、等待…

【Linux】多线程编程

目录 1. 线程基础知识 2. 线程创建 3. 线程ID&#xff08;TID&#xff09; 4. 线程终止 5. 线程取消 6. 线程等待 7. 线程分离 8. 线程互斥 8.1 初始化互斥量 8.2 销毁互斥量 8.3 互斥量加锁和解锁 9. 可重入和线程安全 10. 线程同步之条件变量 10.1 初始化条件变…

一文了解Tomcat

文章目录 1、Tomcat介绍2、Tomcat使用配置2.1、Tomcat下载启动2.2、Tomcat启动乱码2.3、Tomcat端口号修改 3、Tomcat项目部署4、IDEA中使用Tomcat方式 1、Tomcat介绍 什么是Tomcat ​ Tomcat是Apache软件基金会一个核心项目&#xff0c;是一个开源免费的轻量级web服务器&#x…

【算法Hot100系列】最长回文子串

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【机器学习】应用KNN实现鸢尾花种类预测

目录 前言 一、K最近邻&#xff08;KNN&#xff09;介绍 二、鸢尾花数据集介绍 三、鸢尾花数据集可视化 四、鸢尾花数据分析 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Fil…

js基础入门

先来一点js基础&#xff0c;其实js大部分的时候都在处理对象或者数组。 对象四个基本操作&#xff1a;增删改查 掌握元素的增删改查&#xff0c;了解如何拷贝&#xff0c;深拷贝和浅拷贝的区别。详情见代码 <script>//创建对象一共有三种赋值声明的语法let obj{} //赋值…

大数据存储技术(3)—— HBase分布式数据库

目录 一、HBase简介 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;特点 &#xff08;三&#xff09;HBase架构 二、HBase原理 &#xff08;一&#xff09;读流程 &#xff08;二&#xff09;写流程 &#xff08;三&#xff09;数据 flush 过程 &#xf…

Java stream 进阶版

1、Stream 概述 Java 8 引入了 Stream API,它是一种用于简化集合和数组操作的强大工具。Stream API 允许我们将集合或数组视为流,并在流上进行各种操作,如筛选、排序、聚合等。 Stream API 的核心概念是 Stream 流,它代表了一个数据流,其中包含了一系列的元素。这些元素…

【LeetCode刷题-排序】--179.最大数

179.最大数 思路&#xff1a; 方法&#xff1a;自定义排序 class Solution {public String largestNumber(int[] nums) {if(nums null || nums.length 0){return "";}//将每个数字转换成字符串String[] strs new String[nums.length];for(int i 0;i < nums.l…

怎样长时间保持SSH会话连接不断开?

操作场景 使用SSH方式登录CentOS Stream操作系统的云服务器时&#xff0c;过一段时间就会自动断开连接。 该文档适用于CentOS/EulerOS系统。 操作方法 编辑/etc/ssh/sshd_config文件设置心跳&#xff0c;保持连接。 编辑/etc/ssh/sshd_config&#xff0c;添加配置项&#x…

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

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

scrapy post请求——百度翻译(十四)

scrapy处理 post 请求 爬取百度翻译界面 目录 1.创建项目及爬虫文件 2.发送post请求 1.创建项目及爬虫文件 scrapy startproject scrapy_104 scrapy genspider translate fanyi.baidu.com 2.发送请求 post请求需要传递参数&#xff0c;所以就不能用start_urls和parse函数了&…

飞天使-docker知识点6-容器dockerfile各项名词解释

文章目录 docker的小技巧dockerfile容器为什么会出现启动了不暂停查看docker 网桥相关信息 docker 数据卷 docker的小技巧 [rootlight-test playbook-vars[]# docker inspect -f "{{.NetworkSettings.IPAddress}}" d3a9ae03ae5f 172.17.0.4docker d3a9ae03ae5f:/etc…

QT----第三天,Visio stdio自定义封装控件,鼠标事件,定时器,事件分发器过滤器,绘图事件

目录 第三天1 自定义控件封装2 QT鼠标事件3 定时器4 event事件分发器5 事件过滤器6 绘图事件Qpainter 源码&#xff1a;CPP学习代码 第三天 1 自定义控件封装 新建一个QT widgetclass&#xff0c;同时生成ui,h,cpp文件 在smallWidget.ui里添加上你想要的控件并调试大小 回到…

《Linux C编程实战》笔记:一些系统调用

目录 dup和dup2函数 fcntl函数 示例程序1 示例程序2 ioctl函数 dup和dup2函数 #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd): dup 函数复制 oldfd 参数所指向的文件描述符。 参数&#xff1a; oldfd&#xff1a;要复制的文件描述符的…

zookeeper4==zookeeper源码阅读,FOLLOWER收到了需要LEADER执行的命令后各节点会执行什么

上面已经阅读并观察了节点确定自己的身份后会做些什么&#xff0c;大致就是比对双方信息然后完成同步。 本篇阅读&#xff0c; FOLLOWER收到了需要LEADER执行的命令后&#xff0c;怎么同步给LEADER的&#xff0c;并且LEADER会执行什么操作。 源码启动zkCli用于测试 将原本的代…

技术阅读周刊第十期

技术阅读周刊&#xff0c;每周更新。 周四加了个班&#xff0c;周五没缓过来&#xff0c;就推迟到今天更新了 历史更新 20231117&#xff1a;第六期20231124&#xff1a;第七期20231201&#xff1a;第八期20231215&#xff1a;第九期 Golang: 14 Shorthand Tricks You Might No…

LLM中的Prompt提示

简介 在LLM中&#xff0c;prompt&#xff08;提示&#xff09;是一个预先设定的条件&#xff0c;它可以限制模型自由发散&#xff0c;而是围绕提示内容进行展开。输入中添加prompt&#xff0c;可以强制模型关注特定的信息&#xff0c;从而提高模型在特定任务上的表现。 结构 …

hive数据仓库工具

1、hive是一套操作数据仓库的应用工具&#xff0c;通过这个工具可实现mapreduce的功能 2、hive的语言是hql[hive query language] 3、官网hive.apache.org 下载hive软件包地址 Welcome! - The Apache Software Foundationhttps://archive.apache.org/ 4、hive在管理数据时分为元…

『踩坑记录』IDEA Spring initialzr新建Spring项目不能选择jdk8的解决方法

问题描述 Spring initializr新建Spring项目不能选低版本java 解决方法 默认官方start.spring.io已不支持自动生成低版本jkd的Spring项目&#xff0c;自定义用阿里云的starter即可 用阿里云的就能支持低版本jdk了 完 欢迎关注我的CSDN博客 &#xff1a;Ho1aAs 版权属于&a…