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…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
