news 2026/8/11 21:54:30

C语言中的动态内存分配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言中的动态内存分配

在很多场景,数据的大小是在运行时才能确定,编译阶段无法确定数据长度;或者有大块的数据需要存放,但是栈空间不够;或者某些参数需要实现跨函数传递;或者需要实现可变的数据结构。当面临这些问题时,我们往往想到动态分配内存。本文将主要讲在C语言中,动态内存分配的4个常用函数,以及使用注意事项。
一、为什么要用动态内存
栈内存存放局部变量,大小编译期确认,空间很小(通常只有几MB),函数结束自动销毁
堆内存空间大,动态分配,大小运行时确定,但是必须手动管理
原因1:【主要原因】运行时才知道需要多大内存
静态数组写大了浪费内存,写小了会溢出,动态内存要多少给多少
例如:用户输入、读取文件、网络接收的数据,程序跑起来才知道要多少数据,没有办法提前写死。
原因2:突破栈空间限制
栈空间很小,一般就1-8MB左右,大数据不能放在栈上,必须放到堆。
原因3:内存生命周期不受函数作用域限制
栈上的局部变量,函数执行完毕就自动释放了,不能继续函数外使用
动态内存:函数结束,堆内存依然存在,必须手动free才释放
eg:局部数组,函数返回后内存销毁,返回指针就是也指针
原因4:实现可边长数据结构
链表、队列、树、哈希表,全部离不开动态内存。
链表每新增一个节点,就要malloc一块内存节点(没有动态内存,就写不出链表)
二、四种常用动态内存函数
1、四种对比

函数参数内存初始化功能
mallocmalloc(字节数)不初始化(垃圾值)分配指定大小堆内存
calloccalloc(元素个数,每个大小)全部置0分配数组,自动清零
reallocrealloc(旧指针,新总字节)旧数据保留,新增部分不初始化修改已分配内存大小,扩容缩容
freefree(指针)-释放堆内存
malloc和realloc分配的空间生存期,是随进程持续性,不是随代码块持续性。
2、malloc
作用:分配X字节的堆内存,不会初始化内存,里面为随机值。分配成功返回内存首地址,分配失败返回NULL
#include<stdio.h>#include<windows.h>#include<math.h>intmain(){SetConsoleOutputCP(65001);SetConsoleCP(65001);//在堆上申请10个连续int内存空间int*p=(int*)malloc(10*sizeof(int));if(p==NULL){printf("动态内存分配失败\n");}else{printf("动态内存分配成功\n");for(inti=0;i<10;i++){printf("%p,存放的内容%lx\n",&p[i],p[i]);}}free(p);//用完释放p=NULL;// 置空,防止野指针return0;}

运行结果:

malloc分配的内存不会自动初始化,所有元素默认是随机垃圾值,使用前建议手动赋值。
3、calloc
calloc(num,size)
作用:分配num个元素,每个占用size字节,分配完成自动全部初始化为0
和malloc的区别:calloc会清零,malloc不会。

//上面的malloc变为callocint*p=(int*)calloc(10,sizeof(int));

运行结果:

4、realloc
realloc(ptr,new_size)
作用:重新修改已分配好的堆内存,扩容或缩容
ptr:之前得到的指针
newsize:新的总字节数
注意:
如果后面堆空间足够,直接原地扩容,返回原来的地址
如果后面不够,堆找一块全新内存,把旧内容复制过去,释放旧内存,返回新地址
失败返回NULL,原来旧内容不会释放
realloc(ptr,0):长度为0,是把原来的空间释放

#include<stdio.h>#include<windows.h>#include<math.h>intmain(){SetConsoleOutputCP(65001);SetConsoleCP(65001);//在堆上申请10个连续int内存空间,并将内存的首地址赋值给整型指针pint*p=(int*)calloc(5,sizeof(int));int*tmp=(int*)realloc(p,10*sizeof(int));if(p==NULL){printf("动态内存分配失败");}else{printf("-----动态内存分配成功-----\n");for(inti=0;i<5;i++){printf("%p,存放的内容%lx\n",&p[i],p[i]);}if(tmp!=NULL){printf("-----重新分配成功-----\n");p=tmp;for(inti=0;i<10;i++){printf("%p,存放的内容%lx\n",&p[i],p[i]);}}else{printf("-----重新分配失败-----\n");//分配失败,p仍指向旧内存,可以继续使用printf("%p\n",&p);}}free(p);//用完释放p=NULL;// 置空,防止野指针return0;}

运行结果:

注意:realloc直接用原指针接收返回值,失败会导致内存泄漏(例子中直接写p=realloc(p,newsize);如果失败p被赋值为NULL,原内存地址丢失,直接内存泄漏)。
realloc(NULL,n)等价于malloc(n)
5、free释放内存
作用:释放堆内存,还给操作系统
规则
参数必须是malloc、realloc、calloc返回的地址,不能传栈变量地址
free之后,原来的指针变量仍然保存旧地址,变为野指针,建议手动赋值为NULL
不能重复free同一个指针,程序会崩溃
free(NULL)是安全的,什么都不做

三、使用注意事项
1、实际项目大量使用动态内存(malloc、realloc、calloc、free),但是不能无脑使用,滥用会付出巨大代价
内存泄漏:忘记free,程序越跑内存占用越高,长期运行服务直接卡死。
野指针:free之后,继续使用,重复free,直接崩溃
realloc坑点,分配失败处理麻烦
频繁malloc、free会产生内存碎片,长时间运行内存效率下降

所以:
小固定大小缓冲区,优先栈数组,不要malloc
malloc和free尽量配对,谁申请,谁释放
嵌入式设备内存很小,尽量少用动态内存,必要时禁止malloc
2、垃圾内存/内存泄漏

char*p=malloc(10);chara;p=&a;//p本来指向10字节的动态内存分配的空间,现在指向a

上述代码,没有任何指针会指向那段动态内存分配的空间,并且那段空间不会释放,变为垃圾内存(或说内存泄漏)
解决办法:
方案一:p指向其他对象之前先释放

free(p);p=&a;

方案二:p指向其他对象之前,给那段空间找一个索引指针

char*q=p;//后面可以通过q来释放这段空间。p=&a;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/11 21:53:09

5分钟快速上手:免费开源AI生成平台Open Generative AI完全指南

5分钟快速上手&#xff1a;免费开源AI生成平台Open Generative AI完全指南 【免费下载链接】Open-Generative-AI Unrestricted Open-source alternative to AI video platforms — Free AI image & video generation studio with 500 models (Flux, Midjourney, Kling, Sor…

作者头像 李华
网站建设 2026/8/11 21:52:45

终极越狱指南:palera1n深度解析与A8-A11设备完整越狱实战

终极越狱指南&#xff1a;palera1n深度解析与A8-A11设备完整越狱实战 【免费下载链接】palera1n Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher. 项目地址: https://gitcode.com/GitHub_Trending/pa/palera1n 面对iOS系…

作者头像 李华
网站建设 2026/8/11 21:51:49

Visual Studio中高效配置与优化Eigen库:从入门到性能调优

1. 项目概述&#xff1a;为什么要在VS里折腾Eigen&#xff1f;如果你正在用C做点跟数学、物理或者图形学沾边的东西&#xff0c;比如机器人控制、计算机视觉、或者就是单纯想解个大型方程组&#xff0c;那你大概率绕不开一个叫Eigen的库。它不是个新玩意儿&#xff0c;但在高性…

作者头像 李华
网站建设 2026/8/11 21:47:12

如何在10分钟内完成AI规范驱动开发全流程:cc-sdd终极指南

如何在10分钟内完成AI规范驱动开发全流程&#xff1a;cc-sdd终极指南 【免费下载链接】cc-sdd Turn approved specs into long-running autonomous implementation. A minimal, adaptable SDD harness with Agent Skills for Claude Code, Codex, Cursor, Copilot, Windsurf, O…

作者头像 李华
网站建设 2026/8/11 21:45:07

Fnet 云网安 260810

&#x1f6e1;️网络安全云一体化运营中心 7x24主动监控与专家值守&#xff0c;网络可用性99.99%&#xff0c;安全事件100%闭环&#xff0c;云资源一站式管理 今日热点 Top 5 S1 OpenAI Astra模型网络安全能力逼近Critical阈值&#xff0c;OpenAI主动放缓发布并升级安全管控 …

作者头像 李华
网站建设 2026/8/11 21:42:21

10分钟极速上手:Hermes WebUI容器化部署与AI助手体验全攻略

10分钟极速上手&#xff1a;Hermes WebUI容器化部署与AI助手体验全攻略 【免费下载链接】hermes-webui Hermes WebUI: The best way to use Hermes Agent from the web or from your phone! 项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui 你是否厌倦了…

作者头像 李华