news 2026/10/2 17:38:44

动态内存管理(c++方向必看)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
动态内存管理(c++方向必看)

引言:

学 C 的时候,我一度觉得malloc挺多余——数组不是挺好用吗?

直到写了个小练习:让用户输入一串数字再排序。写完发现卡住了,数组长度写多少?写 10,用户输入 11 个就崩;写 1000,又嫌浪费,万一输入 1001 个呢。

关键是,到底有几个数字,我写代码的时候根本不知道,得等程序跑起来才清楚。malloc解决的就是这个:运行时再决定要多少内存,代价是这块内存从此归你管——用完得free,不能越界,free完也不能再用。

动态内存管理也是学好数据结构的前置知识点。

这篇就来讲清楚这几件事。

目录

1.为什么要有动态内存分配

2.malloc和free

2.1malloc

2.2free

3.开辟成功和失败的案例

3.calloc和realloc

3.1calloc

3.3realloc


1.为什么要有动态内存分配

我们已经掌握的的内存开辟方式有:

int val = 20; //在栈空间上开辟四个字节 char arr[10] = { 0 }; //在栈空间上开辟10个字节的连续空间

但是上述开辟空间的方式有两个特点:

1.空间开辟大小是固定的

2.数组在申明的时候,必须指定数组的长度,数组空间⼀旦确定了大小不能调整

但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运⾏的时候才能知 道,那数组的编译时开辟空间的方式就不能满足了。

C语言引入了动态内存开辟,让程序自己可以申请和释放空间,就比较灵活了。

2.malloc和free

2.1malloc

C语言为我们提供了一个动态内存开辟的函数

void* malloc (size_t size);

功能:向内存的堆区申请一块连续可用的空间,并返回指向这块空间的起始地址。

1. 如果开辟成功,则返回这块空间的起始地址。

2.如果开辟失败,则返回⼀个 • 返回值的类型是 NULL 指针,因此malloc的返回值⼀定要做检查。

3.返回值的类型是void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使⽤者自己来决定。

4. 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器

2.2free

C语言提供了一个用于做动态内存的释放和回收的函数:free

void free (void* ptr);

free函数用来释放动态开辟的内存,就像一个图书馆,不能一直借书但是从来不还书,这样会出问题的,malloc和free都声明在stdilb.h头文件中。

如果参数ptr指向的空间不是动态开辟的,那函数free的行为是未定义的。

如果参数ptr是NULL指针,则函数什么都不需要做。

3.开辟成功和失败的案例

#include<stdio.h> #include<stdlib.h> int main() { int* p = (int*)malloc(20);//在堆区上申请20个字节的空间 if (p == NULL) { perror("use malloc"); return 1; } //使用空间 int i = 0; for (i = 0; i < 5; i++) { p[i] = i + 1; } //释放内存 free(p); return 0; }

当程序指向完free这一行,我们使用malloc开辟的内存就被回收掉了,但是当我们把地址还掉之后,p还指向原来的地址,此时的p就是野指针,这个时候给他一个空指针可以了,就像给野狗套上铁链子。

当我们把编译器环境从x64改成x86,并且在malloc中输入特别大的数字,动态内存的开辟就有可能失败,错误信通过perror函数打印出来。

3.calloc和realloc

3.1calloc

C语言还提供了一个函数calloc,calloc也能用来动态内存分配

void* calloc (size_t num, size_t size);

函数的功能是为num个⼤⼩为size的元素开辟⼀块空间,并且把空间的每个字节初始化为0

与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0。

int main() { int* p = (int*)calloc(5, sizeof(int)); if (p == NULL) { perror("use malloc"); return 1; } //使用空间 int i = 0; for (i = 0; i < 5; i++) { p[i] = i + 1; } //释放内存 free(p); p = NULL; return 0; }

malloc和calloc仅仅在初始化上有区别,其他方面是没有区别的。

3.3realloc

realloc的出现使得动态内存管理更加灵活

有时我们会觉得内存过小不够用,有时候内存过大又会产生浪费,为了更合理的使用内存,我们会对内存的大小做灵活调整,realloc就可以做到对动态开辟内存大小的调整。

void* realloc (void* ptr, size_t size);

功能:

重新调整之前分配的内存块的大小,它可以在不丢失原有数据的情况下,扩大或缩小动态分配的内存块。

参数:

ptr是要调整的内存空间的起始地址,如果ptr是NULl指针,realloc函数的功能类似于malloc函数。

size调整之后新大小,单位是字节。

返回值:

成功:返回一个指向重新分配的内存块的void*类型指针。这个指针可能与原来的指针不同。
失败:如果内存重新分配失败,返回 NULL,并且原来的内存块保持不变。

int main() { int* p = (int*)calloc(5, sizeof(int)); if (p == NULL) { perror("use malloc"); return 1; } //使用空间 int i = 0; for (i = 0; i < 5; i++) { p[i] = i + 1; } //希望空间能放10个整形 int* ptr = realloc(p, 10 * sizeof(int)); if (ptr == NULL) { perror("use realloc"); return 1; } else { p = ptr;//继续使用p来维护空间 } //继续使用 for (i = 5; i < 10; i++) { p[i] = i + 1; } free(p); p = NULL; return 0; }

注意:这里不能直接使用p来接收realloc的结果,因为p本身就指向了一块空间,如果realloc开辟失败,那么p直接被置为NULL了,所以我们可以先创建一个ptr来接收,待确认空间开辟成功,再让p接收。

使用realloc调整空间存在两种情况:

1.原有的空间后有足够大的空间,此时拓展内存就直接在原有内存之后直接追加内存,原来空间的数据不发生变化

2.当原有空间之后没有足够多的空间时,扩展的方法是在堆空间另找一个合适大小连续的空间来使用,并返回新的地址,原来空间中存放的数据会复制过来,随后旧空间就释放掉了。

旧空间:”我免费了“(free)

因为篇幅原因动态内存暂时就写到这,下一篇会把常见的动态内存错误,一些经典的面试题,柔性数组等知识点讲清楚。

再次感谢各位码友的观看,祝我们都能实现自己的理想!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 17:38:09

设计模式考试能力训练系统:从题干解码到架构决策

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 17:37:31

BCM、EPS、SAS、VCU实战解析:从物理形态到故障诊断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 17:31:47

免费智能大纲能用什么付费才能买什么

挑写作平台的人多半先落到价格页&#xff0c;看到「免费」二字就注册&#xff0c;真正用起来才发现能做和不能做的部分差别不小。与其纠结谁的价格低&#xff0c;不如把免费智能大纲能免费用到什么程度、付费之后换来哪些能力这两件事拆开看清。知学术AIPaperGPT在这条界线上写…

作者头像 李华
网站建设 2026/10/2 17:31:41

江西南昌竞天汽车改装实力怎么样

江西南昌竞天汽车改装实力怎么样?江西竞天汽车服务有限公司(简称江西竞天改装)给出了一个清晰的答案&#xff1a; 手机&#xff1a;18679126262 官网地址&#xff1a;http://www.jxjtgz.com/ 作为江西本土全流程自营的高端汽车内饰定制改装源头工厂&#xff0c;专注豪车、超跑…

作者头像 李华