动态分配内存
目录
前言
一.malloc,free函数
1.malloc,free函数原型
2.使用方法
3.具体实例
4.注意事项
二.calloc函数
1.calloc函数原型
2.主要特点
3.使用案例
三.realloc函数
1.realloc函数原型
2.使用案例
3.注意事项
前言
动态内存是指在程序运行时,按需分配和释放的内存空间。这种内存分配不在编译时固定,而是在程序执行过程中,根据实际需要分配,并且可以手动释放。
以下介绍的函数都包含于头文件<stdlib.h>
为什么使用动态内存?
1.灵活性高。动态内存可以根据需要分配内存块。
2.避免浪费内存。动态内存允许程序根据需要分配精确的内存量,从而更有效地使用内存资源。
一.malloc,free函数
malloc是 C 标准库中用于动态内存分配的函数。它从堆(heap)中分配指定字节数的内存,并返回指向这块内存的指针。如果内存分配失败,它会返回NULL。
free函数是C标准库中的一个函数,用于释放由动态内存分配函数(如malloc、calloc或realloc)分配的内存。它的作用是将不再需要的动态内存归还给操作系统,防止内存泄漏。
1.malloc,free函数原型
void* malloc(size_t size);
- size:要分配的内存大小,以字节为单位。
- 返回值:成功时,返回指向已分配内存块的指针;失败时,返回
NULL。- void*:返回值类型
void free(void* ptr);
参数:
ptr:一个指向要释放内存块的指针,这个指针必须是通过malloc、calloc或realloc返回的指针。如果ptr为NULL,free不会执行任何操作。返回值:
free没有返回值。
2.使用方法
(1)内存分配,如:
int* p = (int*)malloc(sizeof(int)); // 为一个 int 类型变量分配内存
(2)判断是否开辟空间成功(如果没有开辟成功,直接使用指针可能回答导致程序崩溃,未定义行为等),如:
if (p == NULL) {perror("malloc");//打印错误信息的函数return 1;//分配失败,退出程序
}
(3)释放内存(防止内存泄露),如:
free(p);
(4)将指针置为空(防止指针在释放内存地址后还指向原来那个地址,相当于野指针,可能会导致未定义行为或者程序崩溃等等),如:
p = NULL;
3.具体实例
#include<stdio.h>
#include<stdlib.h>
int main() {int* arr = (int*)malloc(sizeof(int) * 10);//或者int* arr=(int*)malloc(40);//判断是否分配内存成功if (arr == NULL) {perror("malloc");//打印错误信息return 1;//分配失败,退出程序}//初始赋值for (int i = 0; i < 10; i++) {arr[i] = i + 1;}//打印结果for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}//释放内存free(arr);//将arr置为空arr = NULL;return 0;
}
需要注意的是:
在int* arr = (int*)malloc(sizeof(int) * 10);这一语句中
1.(int*)是强制转换类型,将原本的返回值类型void*转化为我们需要定义的数据类型,当然这里我们定义的是int*类型的。
2.sizeof(int)*10是int类型的字节数乘以10,即我们要开辟4*10=40个字节,开辟10个整型的空间,当然我们也可以这么写malloc(40),前提是你要计算好你需要开辟的字节数,否则在没有开辟够这么多的字节数的情况下越界访问数组可能会导致程序崩溃或者无限循环等的行为。
4.注意事项
malloc开辟的空间是没有创建初始值的。
举例如下:
#include<stdio.h>
#include<stdlib.h>
int main() {int* p = (int*)malloc(sizeof(int) * 5);for (int i = 0; i < 5; i++) {printf("%d ", p[i]);}return 0;
}
结果是随机值:

二.calloc函数
calloc是 C 语言中的标准库函数,用于动态分配内存。与malloc类似,calloc也用于在堆上分配一块内存
1.calloc函数原型
void* calloc(size_t num, size_t size);
- num:要分配的元素个数。
- size:每个元素的大小(以字节为单位)。
2.主要特点
(1)分配并初始化内存为零:
calloc会分配一块内存,并将这块内存中的所有字节初始化为0。这与malloc的行为不同,malloc仅仅分配内存,但不对内存进行初始化,内存中的内容可能是垃圾值。
(2)两个参数
与
malloc不同,calloc需要两个参数:第一个参数是要分配的元素个数,第二个参数是每个元素的大小。malloc只需要一个参数(总内存大小),而calloc的目的是让用户更加清晰地定义数组类型的内存分配。
3.使用案例
#include <stdio.h>
#include <stdlib.h>int main() {int* arr = (int*)calloc(5, sizeof(int)); // 分配5个int大小的空间,且初始化为0if (arr == NULL) {printf("Memory allocation failed!\n");return 1;}// 输出分配并初始化的数组for (int i = 0; i < 5; i++) {printf("%d ", arr[i]); // 输出结果将是 0 0 0 0 0}printf("\n");// 使用完成后释放内存free(arr);arr=NULL; return 0;
}
结果如图:

三.realloc函数
realloc函数用于调整已经分配的动态内存的大小
1.realloc函数原型
void* realloc(void* ptr, size_t size);
ptr:指向已经通过malloc,calloc或者realloc分配的内存。如果ptr是NULL,realloc的行为与malloc类似,分配一块新的内存。size:新分配的内存大小,以字节为单位。如果size为 0,realloc的行为与free类似,会释放ptr指向的内存。
2.使用案例
(1)扩大内存
#include <stdio.h>
#include <stdlib.h>int main() {int* arr = (int*)malloc(5 * sizeof(int)); // 分配5个int的内存if (arr == NULL) {perror("malloc");return 1;}// 初始化数组for (int i = 0; i < 5; i++) {arr[i] = i;}//第一次打印for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");// 调整数组大小,增加到10个intint* new_arr = (int*)realloc(arr, 10 * sizeof(int));if (new_arr == NULL) {perror("realloc");free(arr); // 如果失败,释放原来的内存arr = NULL;return 1;}// 如果重新分配成功,继续使用新数组arr = new_arr;// 初始化新增加的部分(第二次打印)for (int i = 5; i < 10; i++) {arr[i] = i;}// 输出数组for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}printf("\n");// 释放内存free(arr);arr = NULL;return 0;
}
结果如图:

(2)缩小内存
#include <stdio.h>
#include <stdlib.h>int main() {// 分配 10 个 int 大小的内存int* arr = (int*)malloc(10 * sizeof(int));if (arr == NULL) {perror("malloc");return 1;}// 初始化数组for (int i = 0; i < 10; i++) {arr[i] = i + 1;}printf("初始10个元素:\n");for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}printf("\n");// 使用 realloc 缩小数组到 5 个 intint* new_arr = (int*)realloc(arr, 5 * sizeof(int));if (new_arr == NULL) {perror("realloc");free(arr); // 如果 realloc 失败,释放原来的内存arr = NULL;return 1;}// 如果 realloc 成功,继续使用缩小后的数组arr = new_arr;printf("缩小后的元素:\n");for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");// 释放缩小后的内存free(arr);arr = NULL;return 0;
}
结果如图:

注意事项:
- 在缩小内存时,数组后面的数据会丢失。程序只能访问缩小后剩余的那部分数据。
-
缩小内存后,应确保访问的索引在新分配的范围内,避免越界访问。
3.注意事项
- 扩展/缩小内存:
realloc可以扩展或者缩小已经分配的内存块。如果扩展,之前的数据会保留;如果缩小,超出部分会被释放。- 原内存的保留:如果
realloc需要移动内存块(例如在当前内存空间不足的情况下),它会自动分配新内存并将旧内存的数据复制过去,原来的内存块会被释放。- 失败时不释放原内存:如果
realloc失败,它不会释放原来的内存,程序可以继续使用原来的
除了这三点,我们还要注意一点,我们来看一下代码:
就是用原来的指针接收申请的空间
#include <stdio.h>
#include <stdlib.h>
int main()
{int* ptr = (int*)malloc(100);if (ptr != NULL){//业务处理 }else{return 1;}//扩展容量 ptr = (int*)realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?) free(ptr);return 0;
}
问题:
- 如果
realloc申请失败,会返回NULL。此时,ptr的原有地址(即之前分配的内存)将会被丢失,导致 内存泄漏。由于ptr被覆盖成NULL,无法再释放之前申请的内存,也无法继续使用。
相关文章:
动态分配内存
目录 前言 一.malloc,free函数 1.malloc,free函数原型 2.使用方法 3.具体实例 4.注意事项 二.calloc函数 1.calloc函数原型 2.主要特点 3.使用案例 三.realloc函数 1.realloc函数原型 2.使用案例 3.注意事项 前言 动态内存是指在程序运行时,按需分配和…...
Unity Input System自动生成配置
参考视频 创建及配置新输入系统 New Input System|Unity2022.2 最新教程《勇士传说》入门到进阶|4K_哔哩哔哩_bilibili ProjectSettings设置 Unity编辑器菜单栏选择Edit->Project Settings->Player->Other Settings,将Api Compatibility Level…...
【Windows】在任务管理器中隐藏进程
在此前的一篇,我们已经介绍过了注入Dll 阻止任务管理器结束进程 -- Win 10/11。本篇利用 hook NtQuerySystemInformation 并进行断链的方法实现进程隐身,实测支持 taskmgr.exe 的任意多进程隐身。 任务管理器 代码: // dllmain.cpp : 定义 …...
【TypeScript学习】TypeScript基础学习总结二
主要记录ts中的类、接口与泛型 1.类 无论是在哪种语言中,类都是面向对象编程(OOP)的一个主要实现方式。能够实现代码更加灵活,更具有结构化。类作用都是提供一个模板,通过类可以创建多个具有相同结构的对象。 // 类的定义,与对象…...
中国电信解锁万亿参数大模型:TeleAI的创新与突破
首个由万卡集群训练出来的万亿参数大模型,已被一家央企解锁。 具体而言,为了推动纯国产人工智能的探索,带来这条新路径的正是中国电信人工智能研究院(TeleAI)。 该研究院由中国电信集团的CTO、首席科学家兼院长李学龙…...
戴尔PowerEdge R840服务器亮黄灯 不开机
最近接修到一台东莞用户的DELL PowerEdge R840 服务器因为意外断电后,无法正常开机的问题, 大概故障现象是 插上电源线 按卡机按钮无响应,无法开机,无显示输出,工程师到现场检修,经过idrac中日志分析&#…...
【前端安全】js逆向之微信公众号登录密码
❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 随着发展,越来越多的登录页面添加了密码加密的措施,使得暴力破解变得不在简单&a…...
C# 泛型使用案例_C# 泛型使用整理
一、系统自带常用的泛型 1.字典,集合 //字典 Dictionary<string, int> dic new Dictionary<string, int>(); //泛型集合 List<int> list new List<int>(); 2.泛型委托,输入参数,输出参数 //泛型 委托---输出参…...
Docker 安装 Citus 单节点集群:全面指南与详细操作
Docker 安装 Citus 单节点集群:全面指南与详细操作 文章目录 Docker 安装 Citus 单节点集群:全面指南与详细操作一 服务器资源二 部署图三 安装部署1 创建网络2 运行脚本1)docker-compose.cituscd1.yml2)docker-compose.cituswk1.…...
Arthas redefine(加载外部的.class文件,redefine到JVM里 )
文章目录 二、命令列表2.2 class/classloader相关命令2.2.3 redefine(加载外部的.class文件,redefine到JVM里 )举例1:加载新的代码,jad/mc 命令使用举例2:上传 .class 文件到服务器的技巧 本人其他相关文章…...
C++教程(三):c++常用的配置文件类型
目录 1. INI 文件 2. JSON 文件 3. YAML 文件 4. XML 文件 5. TOML 文件 6. 二进制配置文件(Protocol Buffers, MessagePack, Avro 等) 总结 在 C 项目中,常用的配置文件类型有多种选择,具体选择取决于项目的复杂性、可读性…...
Arduino Uno控制雨滴传感器模块的设计方案
以下是Arduino Uno控制雨滴传感器模块的设计方案: 一、硬件准备: 1. Arduino Uno 开发板一块。 2. 雨滴传感器模块一个。 3. 杜邦线若干。 4. 9V直流电源一个。 二、硬件连接: 1. 将Arduino Uno板的Vin引脚、GND引脚分别连接到9V直流电…...
华为常见命令手册
常见命令 display ip interface brief —> 查看设备上的每个接口的IP地址【地址/掩码/状态】 display interface gi0/0/0 → 查看该接口的MAC 地址 ipconfig → 查看 PC 上面的 IP地址 display arp → 查看设备的 ARP 表 arp -a → 查看 PC 上面的 ARP 表 display m…...
TinyAP:使用TinyML对抗Wi-Fi攻击的智能接入点
论文标题: 英文:TinyAP: An intelligent Access Point to combat Wi-Fi attacks using TinyML中文:TinyAP:使用TinyML对抗Wi-Fi攻击的智能接入点 作者信息: Anand Agrawal 和 Rajib Ranjan Maiti,来自印…...
grafana频繁DataSourceError问题
背景 随着 Grafana 数据量的不断增加,逐渐暴露出以下问题: Grafana 页面加载缓慢;Grafana 告警频繁出现 DatasourceError 错误。 对于第一个问题,大家可以参考这篇文章:Grafana 加载缓慢的解决方案。 不过…...
python-ds:Python 中的数据结构库(适用于面试的数据结构和算法合集)
在软件开发中,数据结构是组织和存储数据的方式,对算法的效率和程序的性能至关重要。Python 提供了许多内置的数据结构,但在一些复杂的应用场景中,原生数据结构可能无法满足特定需求。这时,一个功能强大、易于使用的数据…...
AccessoriesqueryController
目录 1、 AccessoriesqueryController 1.1、 库存配件查询 1.2、 查询仓库 1.2.1、 //把数据库数据加到表格:跟默认然一行数据进行合并 1.3、 /// 查询 1.3.1、 配件编码查询 1.3.2、 配件名称查询 1.3.3、 配件类型查询 AccessoriesqueryControlle…...
M3u8视频由手机拷贝到电脑之后,通过potplayer播放报错找不到文件地址怎么解决?
该文章前面三节主要介绍M3u8视频是什么,视频播放错误(找不到地址)的解决方法在后面 M3U8是一种多媒体播放列表文件格式,主要用于流媒体播放。 一、文件格式特点 1. 文本文件:M3U8是一个采用 UTF-8 编码的文本文件,这意味着它可…...
【分布式微服务云原生】windows+docker+mysql5.7.44一主一从主从复制
目录 1. 主库设置2. 从库设置3. 验证主从复制内容汇总表格 摘要: 在Windows系统上通过Docker部署MySQL主从复制,以下是详细的步骤和命令,帮助你设置一主一从的MySQL复制环境。 1. 主库设置 步骤1:运行MySQL主库容器 docker run …...
鸿蒙NEXT开发-界面渲染(条件和循环)(基于最新api12稳定版)
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
嵌入式面试常问问题
以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...
使用ch340继电器完成随机断电测试
前言 如图所示是市面上常见的OTA压测继电器,通过ch340串口模块完成对继电器的分路控制,这里我编写了一个脚本方便对4路继电器的控制,可以设置开启时间,关闭时间,复位等功能 软件界面 在设备管理器查看串口号后&…...
解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法
目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客:【写在创作纪念日】基于SpringBoot和PostG…...
