【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;
	}
	else
		pa = 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*类型函数,接收返回值时都要强制类型转换。在堆上申请的空间要即使释放,并置为空指针。每次申请完后要判断申请是否成功等等。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

bugku--文件包含

点击 访问一下index.php 页面报错 既然是文件包含就可以想到php伪协议 这里我们需要访问本地文件系统 构造我们的payload ?filephp://filter/readconvert.base64-encode/resourceindex.php base64解码 得到我们的flag 提交就好啦 ?filephp://filter/readconvert.base64-e…

bugku--source

dirsearch扫一下 题目提示源代码&#xff08;source&#xff09; 也就是源代码泄露&#xff0c;然后发现有.git 猜到是git泄露 拼接后发现有文件 但是点开啥也没有 kali里面下载下来 wegt -r 下载网站的所有内容 ls 查看目录 cd 进入到目录里面 gie reflog 引用日志使用…

过滤(删除)迭代对象中满足指定条件的元素itertools.filterfalse()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 过滤(删除)迭代对象中 满足指定条件的元素 itertools.filterfalse() [太阳]选择题 请问以下代码输出的结果是&#xff1f; a [1, 2, 3, 4, 5] print("【显示】a ",a) import ite…

【SpringBoot】FreeMarker视图渲染

目录 一、FreeMarker 简介 1.1 什么是FreeMarker&#xff1f; 1.2 Freemarker模板组成部分 1.3 为什么要使用FreeMarker 二、Springboot集成FreeMarker 2.1 配置 2.2 数据类型 2.2.1 字符串 2.2.2 数值 2.2.3 布尔值 2.2.4 日期 2.3 常见指令 2.3.2 assign 2.3…

C++ 重载括号运算符示例

重载括号运算符的写法是&#xff0c; 返回值 operator() ( 表达式表 ) 参数个数不限&#xff1b; VC6新建一个单文档工程&#xff1b; 添加一个示例类&#xff0c;比较短&#xff0c;直接加到视类h文件的头部&#xff1b; class A { public:// 重载 括号 () 运算符int oper…

scratch魔法变变变 2023年12月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch魔法变变变 一、题目要求 1、准备工作 2、功能实现 二、案例分析

webpack详细教程

1&#xff0c;什么是webpackwebpack | webpack中文文档 | webpack中文网 Webpack 不仅是一个模块打包器(bundler)&#xff0c;更完整的讲是一个前端自动化构建工具。在 Webpack 看来前端的所有资源文件(s/json/css/img/less/...)都会作为横块处理它将根据模块的依赖关系进行静…

进程概念【linux】

进程基础 在学习进程之前&#xff0c;首先要有一定的计算机硬件和软件基础。 硬件基础&#xff1a;冯诺依曼体系结构 如图&#xff0c;是计算机在硬件上的体系结构。 下面举出一些常见的输入输出设备&#xff08;有些设备只作输出设备&#xff0c;或者只作输入设备&#xff…

xtu oj 1328 数码和

题目描述 一个10进制数n在2∼16进制下可以得到的不同的数码和&#xff0c;求在这些数码和中出现次数最多的数码和。 比如20&#xff0c; 其中数码和2和4分别出现了3次&#xff0c;为最多出现次数。 输入 第一行是一个整数T(1≤T≤1000)&#xff0c;表示样例的个数。 以后每行…

【数据结构(十一·多路查找树)】B树、B+树、B*树(6)

文章目录 1. 二叉树 与 B树1.1. 二叉树存在的问题1.2. 多叉树 的概念1.3. B树 的基本介绍 2. 多叉树——2-3树2.1. 基本概念2.2. 实例应用2.3. 其他说明 3. B 树、B树 和 B*树3.1. B树 的介绍3.2. B树 的介绍3.2. B*树 的介绍 1. 二叉树 与 B树 1.1. 二叉树存在的问题 二叉树…

计算机视觉(P2)-计算机视觉任务和应用

一、说明 在本文中&#xff0c;我们将探讨主要的计算机视觉任务以及每个任务最流行的应用程序。 二、图像内容分类 2.1. 图像分类 图像分类是计算机视觉领域的主要任务之一[1]。在该任务中&#xff0c;经过训练的模型根据预定义的类集为图像分配特定的类。下图是著名的CIFAR…

大数据技术之Hive(超级详细)

第1章 Hive入门 1.1 什么是Hive Hive&#xff1a;由Facebook开源用于解决海量结构化日志的数据统计。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供类SQL查询功能。 本质是&#xff1a;将HQL转化成MapReduce程序 …

TensorFlow学习笔记--(4)神经网络模型-数据集预处理

神经网络初步 以scikit-leran鸢尾花为例 通过scikit-learn库自带的鸢尾花数据集 来测试数据的读入 from sklearn import datasets from pandas import DataFrame import pandas as pdx_data datasets.load_iris().data # .data返回iris数据集所有输入特征 y_data dataset…

【51单片机系列】proteus中创建16x16LED点阵

本文参考来源&#xff1a; Proteus8.6中16x16LED点阵制作教程【Proteus】16乘16点阵滚动播放 文章目录 一、测试proteus中的8x8点阵驱动方式1.1 测试电流通过方向1.2 测试行列控制接口 二、使用proteus中的8x8点阵制作16x16LED点阵三、测试制作的16x16LED点阵四、使用自制的16x…

06 python 文件基础操作

6.1 .1文件读取操作 演示对文件的读取 # 打开文件 import timef open(02_word.txt, r, encoding"UTF-8") print(type(f))# #读取文件 - read() # print(f读取10个字节的结果{f.read(10)}) # print(f读取全部字节的结果{f.read()})# #读取文件 - readLines() # lines…

Python——数据库操作

目录 &#xff08;1&#xff09;安装Flask-SQLAlchemy &#xff08;2&#xff09;使用Flask-SQLAlchemy操作数据库 &#xff08;3&#xff09;连接数据库 •创建数据表 •增加数据 •查询数据 •更新数据 •删除数据 Flask-SQLAlchemy是Flask中用于操作关系型数据库的扩展…

JavaEE:单例模式(饿汉模式和懒汉模式)精讲

前言 什么是单例模式&#xff1f; 其实用通俗的话就是程序猿约定俗成的一些东西&#xff0c;就比如如果你继承了一个抽象类&#xff0c;你就要重写里面的抽象方法&#xff0c;如果你实现了一个接口&#xff0c;你就要重写里面的方法。如果不进行重写&#xff0c;那么编译器就会…

Android BottomSheetBehavior(底部弹窗)

目录 一、BottomSheetBehavior 介绍 二、BottomSheetBehavior 基本使用 2.1 在 CoordinatorLayout 中添加底部工作表&#xff1a; 2.2 在代码中获取 BottomSheetBehavior 实例&#xff1a; 2.3 设置工作表的状态&#xff0c;如展开、折叠等 2.4 工作表的状态 三、Bottom…

redis-学习笔记(Jedis zset 简单命令)

zadd & zrange zadd , 插入的第一个参数是 zset , 第二个参数是 score, 第三个参数是 member 成员 内部依据 score 排序 zrange 返回 key 对应的 对应区间内的值 zrangeWithScore 返回 key 对应的 对应区间内的值和分数 示例代码 zcard 返回 key 对应的 zset 的长度 示例代…

cannot add foreign key constraint问题的解决

cannot add foreign key constraint问题的解决 01 发生场景 当我给mysql数据库表加外键的时候 02 异常发生原因及其解决方式 添加外键时要注意几个关键点&#xff0c;否则很容易失败 1.数据类型一定要一致 添加外键的项和参考项的数据类型一定要一样&#xff0c;这里我报错…