C语言 — 动态内存管理(动态内存函数)
前言
本期分为三篇介绍动态内存管理相关内容,关注博主了解更多
博主博客链接:https://blog.csdn.net/m0_74014525
本期介绍动态内存函数,函数如何使用、函数格式、在使用在所需要的注意点及C/C++程序的内存开辟区域
系列文章
第一篇:C语言 — 动态内存管理(动态内存函数)
第二篇:C语言 — 常见的动态内存错误
第三篇:C语言 — 柔性数组
文章目录
- 前言
- 系列文章
- 一、动态内存分配是什么
- 二、为什么存在动态内存分配
- 三、动态内存函数的介绍
- 1. malloc
- 2. free
- 3. calloc
- 4. realloc
- 四、C/C++程序的内存开辟
- 1. 内存分配区域
- 总结
一、动态内存分配是什么
动态内存分配是指在程序运行期间由程序自己向操作系统请求分配一定大小的内存空间,以存储程序运行时所需的数据。 由于动态分配的内存空间在程序运行期间是可变的,所以它比静态分配更加灵活。
动态内存分配带来的好处是可以根据实际需要动态调整内存大小,从而避免浪费内存。 但是,如果程序员不小心管理动态分配的内存,就可能会导致内存泄漏或者内存溢出等问题,严重影响程序的性能和稳定性。因此,使用动态内存分配时需要注意内存的释放和管理。
常见的动态内存分配函数有 malloc
、calloc
、realloc
等。其中 malloc 分配指定大小的内存块,calloc 分配并初始化一定数量的内存块,realloc 可以重新调整已分配的内存块的大小。
二、为什么存在动态内存分配
我们已经掌握的内存开辟方式有:
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
但是上述的开辟空间的方式有两个特点:
- 空间开辟大小是固定的。
- 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。
有时候我们需要的空间大小在程序运行的时候才能知道,
那数组的编译时开辟空间的方式就不能满足了。
这时候就只能试试动态存开辟了。
三、动态内存函数的介绍
1. malloc
malloc
函数在C语言中用于在程序运行时向内存申请一块指定大小的内存空间。
函数格式:
void* malloc (size_t size);
其中,size_t是一个无符号整数类型,用于表示申请内存的字节数。malloc函数返回一个void指针,指向分配的内存空间的起始地址。如果分配失败,malloc函数返回空指针NULL。
函数特点:
- 如果开辟成功,则返回一个指向开辟好空间的指针。
- 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
- 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
- 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
使用malloc函数申请内存时,需要注意以下几点:
1. | 申请的内存大小应该是变量或数据类型的字节数乘以需要存储或操作的元素个数,以保证申请到足够的内存空间。 |
2. | 申请到的内存空间必须使用free函数进行释放,否则会导致内存泄露。 |
3. | 申请到的内存空间不会被自动初始化,即其中的数据是随机的,需要手动进行初始化。 |
举例演示:
#include <stdio.h>
#include <stdlib.h>int main() {int *p;p = (int*)malloc(10*sizeof(int)); //申请10个int类型数据的内存空间if (p == NULL) { //判断申请是否成功printf("Memory allocation failed.");exit(1);}for (int i = 0; i < 10; i++) { //手动初始化数据*(p+i) = i;}for (int i = 0; i < 10; i++) { //输出数据printf("%d\t", *(p+i));}free(p); //释放内存空间p=NULL; //将指针置为空return 0;
}
2. free
free
函数是 C 语言中用来释放动态分配的内存的函数
函数格式:
void free (void* ptr);
其中,ptr 是之前调用 malloc、calloc 或 realloc函数返回的指针。调用 free 函数后,指针所指向的内存将会被操作系统回收,可以再次被分配给其他程序使用。
函数特点:
- 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
- 如果参数 ptr 是NULL指针,则函数什么事都不做。
使用 free 函数的时候需要注意以下几点:
1. | 只能释放动态分配的内存,不能释放栈或全局变量中的内存。 |
2. | 如果多次释放同一个指针,会导致程序异常。 |
3. | 如果指针为空指针(NULL),则不会进行任何操作。 |
3. calloc
calloc
函数是C语言中的一个内存分配函数,用于在内存中分配指定大小的连续空间,并将其中的每个字节都初始化为0。
函数格式:
void* calloc (size_t num, size_t size);
其中,num表示要分配的元素数量,size表示每个元素的大小。函数返回一个指向新分配内存的指针,如果分配失败则返回NULL。
函数特点:
- 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
- 与malloc函数不同,calloc函数在分配内存时会自动清空分配的内存空间,所以一般用于需要初始化内存的情况。但它的缺点是比malloc函数慢,因为它需要在分配内存时进行清空操作。
使用calloc函数申请内存时,需要注意以下几点:
1. | 申请的内存大小应该是变量或数据类型的字节数乘以需要存储或操作的元素个数,以保证申请到足够的内存空间。 |
2. | 申请到的内存空间必须使用free函数进行释放,否则会导致内存泄露。 |
3. | 申请到的内存空间不会被自动初始化,即其中的数据是随机的,需要手动进行初始化。 |
4. | 区别于malloc,calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。 |
举例演示:
#include <stdio.h>
#include <stdlib.h>
int main()
{int* p = (int*)calloc(10, sizeof(int));if (NULL != p){//使用空间}free(p);p = NULL;return 0;
}
如何对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务
4. realloc
realloc
函数是C语言中的一个库函数,用于重新分配动态分配的内存空间。
1.用于调整现有的内存块大小、
2.分配新的内存块
3.用于释放现有的内存块,当传递给它一个空指针时。
函数格式:
void* realloc(void* ptr, size_t size);
ptr表示指向已经动态分配的内存块的指针。
size表示需要重新分配的内存块的新尺寸。
返回值:如果分配失败,则返回NULL指针;否则返回一个新的指针,指向重新分配后的内存块。
函数特点:
使用realloc函数申请内存时,需要注意以下几点:
1. | 如果新的尺寸大于旧的尺寸,realloc函数将在原来的内存块后面分配额外的内存,使其达到新的尺寸。 |
2. | 如果新的尺寸小于旧的尺寸,realloc函数将会释放一部分内存,使其达到新的尺寸。 |
3. | 如果ptr是空指针,则等同于调用malloc函数。如果size是0,等同于调用free函数。 |
realloc在调整内存空间的是存在两种情况:
- 情况1:原有空间之后有足够大的空间
- 情况2:原有空间之后没有足够大的空间
情况1:
当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
情况2:
当是情况2 的时候,原有空间之后没有足够多的空间时,
扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
由于上述的两种情况,realloc函数的使用就要注意一些。
四、C/C++程序的内存开辟
1. 内存分配区域
C/C++程序内存分配的几个区域:
栈区(stack) | 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 |
堆区(heap) | 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。 |
数据段 (静态区)(static) | 存放全局变量、静态数据。程序结束后由系统释放。 |
代码段 | 存放函数体(类成员函数和全局函数)的二进制代码。 |
总结
本期博客的重要点概况:
malloc
函数:用于动态内存的开辟
calloc
函数:也是用于动态内存开辟,区别于malloc,calloc函数会将每一个字节初始化为0
realloc
函数:用于扩展内存空间,需要注意增加内存的返回,分为情况1和2
free
函数:用于释放动态内存空间
如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。
相关文章:

C语言 — 动态内存管理(动态内存函数)
前言 本期分为三篇介绍动态内存管理相关内容,关注博主了解更多 博主博客链接:https://blog.csdn.net/m0_74014525 本期介绍动态内存函数,函数如何使用、函数格式、在使用在所需要的注意点及C/C程序的内存开辟区域 系列文章 第一篇ÿ…...

Visual ChatGPT:Microsoft ChatGPT 和 VFM 相结合
推荐:使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 什么是Visual ChatGPT? Visual ChatGPT 是一个包含 Visual Foundation 模型 (VFM) 的系统,可帮助 ChatGPT 更好地理解、生成和编辑视觉信息。VFM 能够指…...
基于java理发店预约系统微信小程序设计与实现
摘要 多姿多彩的世界带来了美好的生活,行业的发展也是形形色色的离不开技术的发展。作为时代进步的发展方面,信息技术至始至终都是成就行业发展的重要秘密。不论何种行业,大到国家、企业,小到团体、个人都在多方位的结合信息化技术…...

【软件测试】大厂测工都是这样学习的,你get到了吗?
有不少的软件测试工程师站在“十字路口”迷茫、无助,找不到自己的方向。一切的迷茫都是因为想得太多而做的太少!每位软件测试行业从业者都能意识到目前自己面临的窘境,但能及时作出改变,顺应时代变化的人还是太少。多数人明明“泰…...

如何使用ONLYOFFICE+ffmpeg来给视频文件打马赛克
如何使用ONLYOFFICEffmpeg来给视频文件打马赛克 我这里之前写过很多关于ONLYOFFICE使用、安装的系列图文,也写过很多关于ffmpeg使用的图文,那么这次继续,把这两个开源软件放在一起,能碰撞出什么火花般的功能来。 这就是给视频文…...
003-依赖注入、属性赋值源码分析
目录 引入作用代码分析InstantiationAwareBeanPostProcessor#postProcessProperties()AutowiredAnnotationBeanPostProcessor查找注入点元数据给注入点注入属性 引入 之前我们了解到BeanDefinition到Bean,经历了 实例化属性赋值初始化 3个步骤现在详细分析下属性赋…...

Elasticsearch 商业启示
上月的“红帽事件”,说明开源软件的“客服模式”行不通,那么,开源软件如何赚钱呢?既不能卖软件,又不能卖支持服务,该怎么办呢?我现在的看法是,只剩下一种模式是可行的,开…...

C++/Qt 读写文件
之前写过两篇跟文件操作相关的博客,有兴趣也可以看一下: C语言读写文件 Qt关于文件路径的处理 先讲一些关于基础文本文件和二进制文件的读写操作,后续将会整理C/Qt关于ini、xml、json、xlsx相关文件的读写操作。 C 相比于C语言使用FILE文…...

linux服务器之-nethogs命令
文章目录 NetHogs 工具安装安装依赖包安装epel源安装Nethogs 使用 NetHogs 工具 NetHogs是一个小型的net top工具,不像大多数工具那样拖慢每个协议或者是每个子网的速度而是依照进程进行带宽分组。 安装 安装依赖包 yum install libpcap libpcap-devel epel-rel…...

《每天5分钟玩转kubernetes》读书笔记
笔记 概念 Pod是脆弱的,但应用是健壮的。 kubelet运行在Cluster所有节点上,负责启动Pod和容器。kubeadm用于初始化Cluster。kubectl是k8s命令行工具。通过kubectl可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。 …...

【RabbitMQ】golang客户端教程4——路由(使用direct交换器)
路由 在上一教程中,我们构建了一个简单的日志记录系统。我们能够向许多接收者广播日志消息。 在本教程中,我们将向它添加一个特性-我们将使它能够只订阅消息的一个子集。例如,我们将只能将关键错误消息定向到日志文件(以节省磁盘…...
Shell脚本学习-for循环结构2
案例:通过脚本实现仅sshd、rsyslog、crond、network、sysstat服务在开机时自启动。 Linux系统在开机的服务通常工作在文本模式3级别,因此只需要查找3级别以上的开启的服务即可。查看命令: chkconfig --list |grep 3:on [rootvm1 ~]# chkco…...

vue 老项目 npm install 报错Python,c++等相关错误
老项目npm install 下载依赖包报错 解决方法: //下载python 1、 npm install --global --production windows-build-tools//配置环境 : 也可暂时不用配置,能用就不用配置(npm config set python "D:\Python27\python.exe&q…...

【c语言初级】c++基础
文章目录 1. C关键字2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4. 缺省参数4.1 缺省参数概念4.2 缺省参数分类 5. 函数重载5.2 C函数重载的原理--名字修饰采用C语言编译器编译后结果 1. C关键字 C是在C的基础之上,容纳进去了面向对象编程思想…...

idea打开传统eclipse项目
打开传统web项目 1.打开后选择项目文件 2.选择项目结构 3.设置jdk版本 4.导入当前项目模块 5.选择eclipse 6. 设置保存目录 7.右键模块,添加spring和web文件 8. 设置web目录之类的,并且创建打包工具 9.如果有本地lib,添加为库 最后点击应用&…...
全国各城市-财政收入-一般预算收入-各项税收-个人所得税(1999-2020年)
个人所得税是一项反映国家财政状况和个人经济水平的重要数据。通过对全国各城市个人所得税数据的研究,可以提供研究者参考的有益信息。首先,个人所得税数据反映了不同城市居民的收入水平。通过对不同城市的个人所得税数据进行比较,可以了解不…...

【动态网页抓取】 :用Python抓取所有内容的指南
一、说明 您在抓取动态网页内容时是否得到了糟糕的结果?不仅仅是你。对于标准抓取工具来说,爬网动态数据是一项具有挑战性的任务(至少可以说)。这是因为当发出HTTP请求时,响应程序的某些部分JavaScript在后台运行&…...

Spring Boot数据访问基础知识与JDBC简单实现
目录 Spring Boot数据访问基础知识 Spring Data ORM JDBC JPA JDBC简单实现 步骤1:新建Maven项目,添加依赖 步骤2:配置数据源—让程序可以访问到 步骤3:配置数据源—让IDEA可以访问到 步骤4:添加数据库和表 …...
ubuntu添加万能头文件
ubuntu的C头文件目录为/usr/include 在/usr/include下新建文件夹 bits sudo mkdir bits进入bits,新建stdc.h,并修改权限为744/777 cd bits;sudo touch stdc.h;sudo chmod 777 stdc.h将以下内容粘贴到stdc.h,保存退出 // C includes used …...
聊一聊关于前端语法 ?? 的那些事
当我们在编写前端代码时,语法是非常重要的。正确的语法可以确保我们的代码能够正常运行,并且易于维护和理解。在本文中,我们将探讨一些前端语法的问题,例如空值合并运算符(??)。 空值合并运算符是ES2020…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...