c语言-实现动态内存管理的库函数

文章目录

  • 前言
  • 一、什么是动态内存分配?
  • 二、malloc()和free()
    • 2.1 malloc()介绍
    • 2.2 malloc()的使用
    • 2.3 free()介绍
  • 三、calloc()
    • 3.1 calloc()介绍
    • 3.2 calloc()使用
  • 四、realloc()
    • 4.1 realloc()介绍
    • 4.2 realloc()使用
  • 总结


前言

本篇文章介绍c语言中实现动态内存管理的库函数,比如malloc()、free()、calloc()、realloc()

一、什么是动态内存分配?

在一般情况下,通过以下方式开辟内存空间

	int var = 20;  //在栈空间开辟4个字节的char str[10] = {0}; //在栈空间开辟10个字节连续的空间

上面开辟空间的方式有两个特点:

  1. 开辟空间的大小是固定的,不可变的
  2. 在栈中开辟,并且在编译时分配空间

当需要在程序运行过程中才能知道所有空间的大小时,这时候就需要动态内存分配。
动态内存分配是指在程序运行过程中,可以动态地向操作系统申请内存空间。
在c语言中,可以借助malloc()、free()、calloc()、realloc()这几个库函数实现动态内存的管理。
在这里插入图片描述


二、malloc()和free()

2.1 malloc()介绍

下面是cplusplus网站关于malloc()函数的介绍,如下:
在这里插入图片描述
作用:申请size个字节内存空间
说明:

  • 申请size个字节的空间
  • 分配的内存空间是没有经过初始化的,存储的是不定值

返回值说明:

  1. 如果传入的参数size为0,返回值为的标准未定义,由实现的编译器决定。
  2. 如果申请成功,返回这块内存空间的起始位置的指针,类型为void*,可以通过强制类型转换为期望解引用的类型
  3. 如果申请失败,返回一个空指针NULL

2.2 malloc()的使用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{//申请40个字节int* p = (int*)malloc(40);//判断申请是否成功if (NULL == p){printf("%s", strerror(errno));return 1;}//使用空间int i = 0;int sz = 40 / sizeof(int);for (i = 0; i < sz; i++){*(p + i) = i;}//打印for (i = 0; i < sz; i++){printf("%d ", *(p + i));}//使用完之后,释放空间free(p);p = NULL;return 0;
}

2.3 free()介绍

下面是cplusplus网站关于free()函数的介绍,如下:
在这里插入图片描述
作用:释放通过malloc()、calloc()、realloc()函数申请的空间
说明:

  • 如果ptr不是指向由malloc()、calloc()、realloc()申请的空间,那么释放时会引起未定义
  • 如果ptr为空指针,那么这个函数什么也不做。
  • 释放ptr指向的空间时,ptr本身的值不会被改变,即ptr依然会指向被释放的空间。所以,在释放ptr指向的空间后,应将ptr置为空指针。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{//申请40个字节int* p = (int*)malloc(40);//判断申请是否成功if (NULL == p){printf("%s", strerror(errno));return 1;}//使用空间int i = 0;int sz = 40 / sizeof(int);for (i = 0; i < sz; i++){*(p + i) = i;}//使用完之后,释放空间free(p);p = NULL;return 0;
}

通过vs的内存监视查看(未释放前)
在这里插入图片描述
利用free()释放p指向的空间后
在这里插入图片描述
通过结果得出,free(p)释放p指向的空间后,p的指向没有改变,为了避免越界访问,因此可以将p = NULL

三、calloc()

3.1 calloc()介绍

下面是cplusplus网站关于calloc()函数的介绍,如下:
在这里插入图片描述
作用:申请一块num个size字节大小的连续空间。
说明:

  • 与malloc()不同之处的是,calloc()会在申请成功后,将每个字节初始化为0
  • 如果传入的参数size为0,返回值为的标准未定义,由实现的编译器决定,且返回值不可解引用。
  • 如果申请成功,返回这块内存空间的起始位置的指针,类型为void*,可以通过强制类型转换为期望解引用的类型
  • 如果申请失败,返回一个空指针NULL

3.2 calloc()使用

申请10个int大小的空间(10*sizeof(int)个字节)

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
//申请10个int的空间
int main()
{int* p = (int*)calloc(10, sizeof(int));if (NULL == p){printf("%s\n", strerror(errno));return 1;}//释放空间free(p);p = NULL;return 0;
}

通过vs的内存监视查看
在这里插入图片描述
calloc()申请成功后,将每个字节初始化为了0,也可利用malloc()+memset()实现。

四、realloc()

4.1 realloc()介绍

下面是cplusplus网站关于realloc()函数的介绍,如下:
在这里插入图片描述

作用:将ptr指向的内存块的大小改变为size个字节大小
说明:

  • 如果ptr是一个空指针,那么realloc()的作用与malloc()一样,都是申请size个字节大小的连续内存
  • realloc()申请内存时,申请得到的内存分为两种情况(扩容:申请大于ptr指向的内存大小
    假设ptr指向的内存块大小为40个字节,现扩容到80个字节:
  1. 在ptr指向的内存块后面直接扩容
    在这里插入图片描述

  2. 开辟一块大小为size的新空间
    在这里插入图片描述
    在这种情况下,在扩容成功后,会将原始内存的内容拷贝到扩容内存中,然后释放原始内存。

4.2 realloc()使用

  1. 传入空指针
    在这里插入图片描述
  2. 扩容
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
int main()
{//申请10个int的空间int* p = (int*)malloc(10*sizeof(int));if (NULL == p){printf("%s\n", strerror(errno));return 1;}memset(p, 0, 40);//扩容将p指向的内存块扩容到80个字节int* pp = (int*)realloc(p, 80);if (pp != NULL){p = pp;pp = NULL;}//释放pfree(p);p = NULL;return 0;
}

通过vs的内存监视查看内存情况
在这里插入图片描述
p和pp指向的空间不相同,说明此次扩容是在新的内存上开辟;同时,pp的前40个字节的内容和p的40个字节的内容是相同的,说明新扩容的内存将原始内存的内容进行了拷贝。


总结

本篇文章介绍了在c语言中实现动态内存管理的四个库函数,malloc()、free()、calloc()、realloc()。

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

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

相关文章

U-Mamba: Enhancing Long-range Dependency for Biomedical Image Segmentation

Abstract 卷积神经网络(Convolutional Neural Networks, cnn)和transformer是生物医学图像分割中最流行的架构&#xff0c;但由于固有的局部性或计算复杂性&#xff0c;它们处理远程依赖关系的能力有限。为了解决这一挑战&#xff0c;我们引入了U-Mamba&#xff0c;一个通用的…

TCP传输数据

TCP客户端 using System; using System.Collections; using System.Collections.Generic; using System.Net.Sockets; using UnityEngine;public class TCPClient {/// <summary>/// 客户端/// </summary>private TcpClient tcpClient;private NetworkStream stre…

二.Winform使用Webview2在Demo1中实现地址简单校验

Winform使用Webview2在Demo1中实现地址简单校验 往期目录回顾添加对于的简单url验证提示通过上节和本节涉及到的函数有 往期目录 往期相关文章目录 专栏目录 回顾 通过一.Winform使用Webview2(Edge浏览器核心) 创建demo(Demo1)实现回车导航到指定地址 我们已经知道了解决资源…

HCIA-HarmonyOS设备开发认证-HarmonyOS简介

目录 前言目标一、HarmonyOS简介1.1、初识HarmonyOS1.2、HarmonyOS典型应用场景 二、HarmonyOS架构与安全2.1、HarmonyOS架构 前言 本章主要介绍HarmonyOS分布式操作系统的概念、关键技术与能力以及HarmonyOS典型的应用场景。 目标 学习完成本课程后&#xff0c;您将能够&…

Vue的指令

Vue的指令 Vue.js 中的指令是一些特殊的标记&#xff0c;用于在模板中指定如何将数据应用到 DOM。 下面是一些基本的 Vue 指令&#xff1a; v-bind: 动态绑定一个或多个属性&#xff0c;或一个组件 prop 到表达式&#xff0c;用于动态绑定 HTML 属性到表达式。常用于绑定 cla…

MySql必知必会

1.什么是BufferPool&#xff1f; Buffer Pool基本概念 Buffer Pool&#xff1a;缓冲池&#xff0c;简称BP。其作用是用来缓存表数据与索引数据&#xff0c;减少磁盘IO操作&#xff0c;提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…

树莓派 Linux - 使用ngrok实现内网穿透

官网 &#xff1a;ngrok | Unified Application Delivery Platform for Developers 简单的注册一下即可 我这里的操作系统是kali Linux 选择linux 启动服务最好使用静态域名 把需要穿透的端口号配置为本地的端口号即可 参考视频 没有服务器&#xff0c;就不能上线网站了&am…

HYBBS 表白墙网站PHP程序源码 可封装成APP

源码介绍 PHP表白墙网站源码&#xff0c;可以做校园内的&#xff0c;也可以做校区间的&#xff0c;可封装成APP。告别QQ空间的表白墙吧。 安装PHP5.6以上随意 上传程序安装&#xff0c;然后设置账号密码&#xff0c;登陆后台切换模板手机PC都要换开启插件访问前台。 安装完…

k8s集群master节点的删除和重新加入

一、剔除master1节点 1&#xff09;删除master1节点 3台master下掉一个&#xff0c;剩下2个master运行基本也没问题。坚持个一两天问题不大。 kubectl drain paas-m-k8s-master-1 --delete-local-data --force --ignore-daemonsets kubectl delete node paas-m-k8s-master-12)…

刚学习的最长不递增子序列的新求法

P1020 [NOIP1999 提高组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 在做这题的时候学到的 我看说是复杂度在O(nlogn)的算法才能通过这题 普通的办法就不行了&#xff08;之前写过&#xff09; 然后我去看题解&#xff0c;学了这种新的方法 网址如下&#x…

Unity 工厂方法模式(实例详解)

文章目录 在Unity中&#xff0c;工厂方法模式是一种创建对象的常用设计模式&#xff0c;它提供了一个接口用于创建对象&#xff0c;而具体的产品类是由子类决定的。这样可以将对象的创建过程与使用过程解耦&#xff0c;使得代码更加灵活和可扩展。 工厂模式的主要优点如下&…

深度学习笔记(九)——tf模型导出保存、模型加载、常用模型导出tflite、权重量化、模型部署

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解&#xff0c;如有遗漏或错误&#xff0c;欢迎评论或私信指正。 本篇博客主要是工具性介绍&#xff0c;可能由于软件版本问题导致的部分内容无法使用。 首先介绍tflite: TensorFlow Lite 是一组工具&#xff0c;可帮助开…

[足式机器人]Part2 Dr. CAN学习笔记- 最优控制Optimal Control Ch07-1最优控制问题与性能指标

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - 最优控制Optimal Control Ch07-1最优控制问题与性能指标

LINUX常用工具之性能分析工具推荐

一、CPU性能分析工具 性能指标 工具 说明 用法举例&#xff1a; 平均负载 Top Uptime Uptime&#xff1a;最简单&#xff1b; Top&#xff1a;提供了更全的指标&#xff08;平均负载、运行队列、整体的CPU使用率以及每个进程状态和CPU使用率&#xff09; Top&#xff1a…

Spring+SprinMVC+MyBatis注解方式简易模板

SpringSprinMVCMyBatis注解方式简易模板代码Demo GitHub访问 ssm-tpl-anno 一、数据准备 创建数据库test&#xff0c;执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Version :…

opendrive-经纬度投影坐标转横轴墨卡托投影坐标

xodr的geoReference标签介绍 经纬度投影 xodr文件projlatlong&#xff0c;说明需要使用经纬度投影代表x,y,z <geoReference>projlatlong ellpsWGS84 datumWGS84</geoReference>xodr文件projtmerc&#xff0c;说明需要使用横轴墨卡托投影(将经纬度投影转为墨卡托投…

【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

针对Java对象压缩及序列化技术的探索之路 序列化和反序列化为何需要有序列化呢&#xff1f;Java实现序列化的方式二进制格式 指定语言层级二进制格式 跨语言层级JSON 格式化类JSON格式化&#xff1a;XML文件格式化 序列化的分类在速度的对比上一般有如下规律&#xff1a;Java…

选择排序(二)——堆排序(性能)与直接选择排序

目录 一.前言 二.选择排序 2.1 堆排序 2.2选择排序 2.2.1 基本思想 2.2.2直接选择排序 三.结语 一.前言 本文给大家带来的是选择排序&#xff0c;其中选择排序中的堆排序在之前我们已经有过详解所以本次主要是对比排序性能&#xff0c;感兴趣的友友可移步观看堆排&#…

世微AP5179 60V高端电流采样降压恒流驱动器 LED车灯备用灯信号灯

产品描述 AP5179是一款连续电感电流导通模式的降压恒流源&#xff0c;用于驱动一颗或多颗串联LED输入电压范围从 5 V 到 60V&#xff0c;输出电流 可达 2.0A 。根据不同的输入电压和 外部器件&#xff0c; 可以驱动高达数十瓦的 LED。 内置功率开关&#xff0c;采用高端电流采样…

python实现带刷新的文本进度条

进度条已执行的部分使用“**”&#xff0c;未执行的部分使用“--”&#xff0c;用print&#xff08;&#xff09;来完成 使用到的函数&#xff1a; time.sleep(),作用是在程序执行过程中暂停一段时间&#xff0c;即会使程序暂停指定的秒数&#xff0c;然后再继续执行后面的代…