C语言:动态内存管理(malloc,calloc,realloc,free)

目录

前言

malloc函数

free函数

calloc函数

realloc函数


前言

在这一章节将讲解动态内存分配,它可以在程序的堆区创建一块内存,在这块内存中存什么值就是由自己决定的了

开辟的空间有两个特点:

1. 空间开辟的大小是固定的

2. 数组在声明时必须指定长度,数组的大小一旦确定就不能调整

在使用这些函数之前我们需要包含他们头文件

#include<stdlib.h>

malloc函数

该函数的作用是开辟一块固定大小连续的空间,并返回指向这块空间的指针

所以它的返回值为void*

里面的参数size是一个以字节为单位的数字,函数会开辟所给的大小

如果malloc开辟空间成功,则按上面所说返回一个指向这块空间的指针

如果malloc开辟空间失败,则会返回NULL指针

因此使用它时一定要进行检查返回值

如果传的size为0,则具体怎么处理看编译器

具体使用malloc函数的代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = malloc(sizeof(int) * 4);
	if (p == NULL)
	{
		perror("malloc fail");
		return 1;
	}
	for (int i = 0; i < 4; i++)
	{
		p[i] = i + 1;
	}
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", p[i]);
	}
	return 0;
}

 首先我们定义了一个int* 类型的指针接收malloc的返回值

并且使用了if 语句判断malloc开辟空间是否成功,如果成功则不会进入if 语句进入下面的语句

然后下面的两个for循环就是正常的给空间赋值和打印,最终结果如下:

但是这样做其实还差了点意思,这个程序其实并不完美,存在内存泄漏的问题

假设我们需要一直跑某一个代码,那么我们如果这样一直使用内存不进行释放的话,迟早有一次内存会被吃满,这种现象叫做内存泄漏

所以为了解决这个问题,我们需要使用另一个函数

free函数

 free是专门用来做动态内存的释放和回收的

该函数没有返回值,参数为一个void* 的指针(想了解void*可以看看我前面的博客)

C语言:指针的基础详解-CSDN博客

注:

1. 如果ptr指向的空间不是动态开辟的,则free函数的行为是未定义的(具体处理方式看编译器)

2. 如果ptr是NULL指针,则函数什么事情都不做

所以与上面动态开辟内存的malloc函数结合起来使用,我们在上面写的代码只需要在最后加上一个free函数释放掉这块空间即可

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = malloc(sizeof(int) * 4);
	if (p == NULL)
	{
		perror("malloc fail");
		return 1;
	}
	for (int i = 0; i < 4; i++)
	{
		p[i] = i + 1;
	}
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

最后free的参数为p表示释放掉p指向的这块动态开辟的空间

并且我们可以在最后将p置为空指针,以防它变成野指针

calloc函数

calloc跟malloc基本差不多

第一个参数num是需要开辟的空间数量

第二个参数size是每个空间的大小

返回值与malloc一样

calloc与malloc的本质区别就是calloc会将开辟的那块空间的每个字节初始化为0

总结:calloc会初始化,malloc不会初始化

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = calloc(4, sizeof(int));
	if (p == NULL)
	{
		perror("malloc fail");
		return 1;
	}
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

 前面的代码我们将malloc换成了calloc,并且将初始化的环节删除了,最终输出结果如下:

可以看到我们并没有给它初始化但是打印出来的结果是0

所以这个函数已经将这块空间给初始化为0了

realloc函数

realloc让动态内存管理更加灵活了

有时候我们会发现申请的空间太小了,有时候又觉得申请的空间太大了浪费,为了合理的使用内存

我们可以使用realloc函数进行调整

第一个参数ptr是要调整的内存地址

第二个参数是调整之后的新大小

 函数返回值为调整之后的内存起始位置

realloc调整空间有两种情况

情况1:原有空间之后有足够大的空间

情况2:原有空间之后没有足够大的空间

如果是情况1则会直接在原来的空间后面直接追加空间,最后返回原来的内存地址

如果是情况2则会在堆空间上另外找一个合适并且有足够大小的空间进行开辟,最后返回新的内存地址 

具体代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = malloc(sizeof(int) * 4);
	if (p == NULL)
	{
		perror("malloc fail");
		return 1;
	}
	int* ptr = realloc(p, sizeof(int) * 6);
	for (int i = 0; i < 6; i++)
	{
		ptr[i] = i + 1;
	}
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", ptr[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

第一个malloc开辟了四个int类型的空间,若此时我们发现不够,则以下用了realloc调整空间

下面使用了ptr来接收realloc将p指向的空间变成6个int类型的空间的起始地址

最后我们给ptr赋值并且打印,结果如下:


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

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

相关文章

零基础学习挖掘PHP网站漏洞

教程介绍 本套课程&#xff0c;分为三个阶段&#xff1a;第一阶段&#xff1a;基础篇 学习PHP开发的基础知识&#xff0c;对PHP常见的漏洞进行分析&#xff0c;第二阶段&#xff1a;进阶篇 实战PHP漏洞靶场&#xff0c;了解市面上的PHP主流网站开发技术&#xff0c;并对市面上…

JAVA获取免费天气

JAVA调用天气代码示例 前沿&#xff1a;最近在开发任务中需要获取每日的实时天气和天气预报&#xff0c;要求还是免费的。在网络上搜索了一下免费的API并有了以下思路 免费API网址&#xff1a;https://dev.qweather.com/docs/api/grid-weather/grid-weather-now/ 调用格林天…

工程企业的未来选择:Java版工程项目管理系统平台与数字化管理的融合

在现代化的工程项目管理中&#xff0c;一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统&#xff0c;结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…

基于Colab训练的yolov4-tiny自定义数据集(可用于OpenCV For Unity)

参考资料文档和视频。 1.打开文档,点击【文件】【在云端硬盘中保存一份副本】,即将文档复制到自己云端硬盘。 2.打开该文件,按文中提示进行。 【代码执行程序】【更改运行时类型】修改运行时为GPU(免费的GPU不好用,收费的好用,某宝上几十元就可用一个月) 步骤1) !git…

大数据面试题 —— Kafka

目录 消息队列 / Kafka 的好处消息队列的两种模式什么是 KafkaKafka 优缺点你在哪些场景下会选择 Kafka讲下 Kafka 的整体结构Kafka 工作原理 / 流程Kafka为什么那么快/高效读写的原因 / 实现高吞吐的原理生产者如何提高吞吐量&#xff08;调优&#xff09;kafka 消息数据积压&…

python爬虫-----输入输出与流程控制语句(第四天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

力扣:字母迷宫,python

这里写自定义目录标题 问题描述题解踩坑记录global和nonlocal关键字的区别&#xff1a;类中可以用实例变量替换全局变量 问题描述 字母迷宫游戏初始界面记作 m x n 二维字符串数组 grid&#xff0c;请判断玩家是否能在 grid 中找到目标单词 target。 注意&#xff1a;寻找单词…

【C++ leetcode】双指针(专题完结)

15. 三数之和 题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的…

P1443马的遍历 典bfs

题目&#xff1a; 代码&#xff1a; #include<algorithm> #include<iostream> #include<cstring> #include<queue>using namespace std;int n,m;int dx[] {-1,-1,-2,-2,1,1,2,2}; int dy[] {-2,2,-1,1,-2,2,-1,1}; bool vis[450][450];struct node{…

秋招打卡算法题第一天

一年多没有刷过算法题了&#xff0c;已经不打算找计算机类工作了&#xff0c;但是思来想去&#xff0c;还是继续找吧。 1. 字符串最后一个单词的长度 public static void main(String[] args) {Scanner in new Scanner(System.in);while(in.hasNextInt()){String itemin.nextL…

Ubuntu 下统计文件数量的命令

参考:https://blog.csdn.net/kxh123456/article/details/123811580 查看当前目录下的文件数量&#xff08;不包含子目录中的文件&#xff09; ls -l|grep "^-"| wc -l实例展示&#xff1a;如下图所示&#xff0c;当前路径下&#xff0c;有2个json文件和2个文件夹&a…

面向对象【Annotation注解】

文章目录 注解概述注解与注释常见的 Annotation最基本的注解使用@Override@Override@SuppressWarnings元注解@Retention@Target@Documented@Inherited自定义注解格式定义使用注解概述 注解(Annotation)是从 JDK5.0 开始引入,以“@注解名”在代码中存在。例如: @Override @D…

EtherCAT转RS232网关在风电领域的应用

开疆智能EtherCAT转RS232网关在风电领域的应用主要体现在以下几个方面&#xff1a; 1.数据采集与传输&#xff1a;在风力发电设备中&#xff0c;传感器和执行器的数据采集和传输至关重要。EtherCAT转RS232网关可以将风力发电设备中的RS232通信协议转换为EtherCAT协议&#xff0…

Unity 布局元素Layout Element

Layout Element是一种用于控制UI元素在布局组件&#xff08;如Horizontal Layout Group、Vertical Layout Group、Grid Layout Group、Content Size Fitter和Aspect Ratio Fitter&#xff09;中的大小和位置的组件。Layout Element组件可以附加到UI元素上&#xff0c;以便在布局…

操作系统—信号量和条件变量实践

文章目录 信号量和条件变量实践1.实验基本环境(1).基本系统环境 2.信号量(1).如何使用信号量?(2).课上的例子(3).打印合法括号序列(4).打印很多条鱼 3.条件变量(1).为什么选择条件变量?(2).还是课上的例子(3).还是合法括号序列 (4).还是打印很多鱼总结 参考资料 信号量和条件…

设计模式之装饰模式解析

装饰模式 1&#xff09;概述 1.定义 动态地给一个对象增加一些额外的职责&#xff0c;在增加对象功能时&#xff0c;装饰模式比生成子类实现更为灵活。 2.作用 装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为。 3.结构图 4.角色 Component&#xf…

编程语言|C语言——C语言标识符的命名规则

1.标识符简介 在计算机高级语言中&#xff0c;用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列统称为标识符。标识符可以简单认为是一个名字&#xff0c;用来标识变量名、常量名、函数名及数组等。变量名a、b、c,符号常量名PI、Pai,函数名printf、scanf等都是标…

题目:忐忑楼梯Ⅱ

问题描述&#xff1a; 解题思路&#xff1a; 利用差分&#xff0c;当第一个以后的差分元素都为零时就代表楼梯高度等于第一个楼梯的高度。为什么是第一个呢&#xff0c;因为以第一个为标准的区间操作数最少。 注意点&#xff1a;每次都只能加一或减一&#xff0c;ans开ll 题解&…

港澳青年看祖国—千名青年创业家内地暨江港青年交流活动在江举行

为聚焦“一点两地”全新定位&#xff0c;助力纵深推进新阶段粤港澳大湾区建设&#xff0c;3月22日&#xff0c;江门市委统战部、团市委、市青联联合香港深水埗区青年发展及公民教育委员会、愿景基金会、香港青年创业家总商会举办千名青年创业家内地行暨江港青年交流活动&#x…

2024/3/27打卡接龙数列——动态规划(线性DP/最长上升子序列)

目录 题目 思路 代码 题目 思路 这个题求最少删除多个个数&#xff0c;其实是求最长的接龙数列&#xff0c;用总个数-接龙数列的个数就是最少删除的个数。 那么如何求解最长的接龙数列的问题。 思考&#xff0c;每个数都有选或不选的两种选项&#xff08;选&#xff1a;可以…