当前位置: 首页 > news >正文

【C语言】动态内存管理

前言

什么是动态内存?

在C语言中,动态内存是指在程序运行时根据实际需求动态分配和释放的内存。与静态内存(在编译时分配,生命周期与程序或函数运行周期相同)不同,动态内存的分配和释放由程序员通过特定的函数手动控制,常用的函数为molloc、free、realloc、calloc,其开辟的空间在堆上

为什么需要动态内存?

int i = 20;
char arr[20];

上面的代码中,是程序在栈上开辟的空间,用于储存变量的,而在栈上开辟的空间有两个特点(都是静态的):

  • 空间开辟大小是固定的
  • 数组在申明的时候,必须指定数组的长度,数组空间一旦确定了大小不能调整

那么,对于程序员来说,我们有时候只有在程序运行后才知道要开辟多少空间给某个变量,而这些已经写死大小的内存就不符合我们的愿景了,所以我们需要动态内存管理,下面我们就对动态内存管理展开说说!
下面所讲的函数均处于 stdlib.h 库中


一、malloc函数

malloc函数是C语言中一个用来开辟内存的函数

void* malloc(size_t size)
  • 参数 :
    size 指定需要分配的内存大小,单位为字节;size_t 是一个无符号整数类型,通常用于表示大小
  • 返回值:
    1. 如果开辟成功,则返回一个指向开辟好空间的指针
    2. 如果开辟失败,则返回一个NULL 指针,因此malloc的返回值一定要做检查

注:返回值的类型是void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自
己来决定;如果参数size 为0,malloc的行为是标准是未定义的,取决于编译器

#include <stdio.h>
#include <stdlib.h>

int main() {
	int* arr = NULL;
	int* tmp = (int*)malloc(sizeof(int) * 10);
	if (tmp == NULL) {
		perror("main()::malloc()");
	}
	else {
		arr = tmp;
	}
	free(arr);
	
	return 0;
}

这里我们就使用了malloc开辟了一块大小为40Byte的内存空间


二、calloc函数

calloc函数是C语言中用于动态分配内存的另一个重要函数,它与malloc类似,但在分配内存后会自动初始化为0

void* calloc(size_t num, size_t size);
  • 参数:
    num:分配的元素个数
    size:每个元素的大小
  • 返回值
    1. 如果开辟成功,则返回一个指向开辟好空间的指针
    2. 如果开辟失败,则返回一个NULL 指针,因此calloc的返回值一定要做检查

malloc 与 calloc 的唯一区别是 calloc 会初始化开辟的空间,用法与 malloc 一样


三、realloc函数

如果我们前面使用了 malloc 或则 calloc 函数开辟了空间,但是我们发现开辟的空间不够用了,还想开辟多一点,或则说发现开辟大了,想缩小,那么我可以使用 realloc 函数,它可以改变之前分配的内存块的大小

void* realloc(void* ptr, size_t size);
  • 参数:
    ptr:指向之前分配的内存块的指针,如果ptr为NULL,realloc的行为等同于malloc
    size:新的内存块的大小(以字节为单位)
  • 返回值:
    1. 如果调整成功,返回指向新分配的内存的指针
    2. 如果调整失败,则返回一个NULL 指针,原内存块不变

对于realloc调整成功返回的指针,分两种情况:

  1. 情况一: 原有内存后面足够多的剩余空间用于拓展,则在原有的空间后面直接拓展,并返回prt指针
  2. 情况二: 原有内存后面没有足够多的剩余空间用于拓展,扩展的方法是: 在堆空间上另找一个合适大小的连续空间来使用,这样函数返回的是一个新的内存地址

在这里插入图片描述

四、free函数

在C语言的库中,专门提供了一个free函数将开辟出来的动态内存释放掉的,函数原型如下:

void free (void* ptr);

注:

  • 如果参数ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的
  • 如果参数ptr 是NULL指针,则函数什么事都不做
#include <stdio.h>
#include <stdlib.h>

int main() {
	int* arr = NULL;
	int* tmp = (int*)malloc(sizeof(int) * 10);
	if (tmp == NULL) {
		perror("main()::malloc()");
	}
	else {
		arr = tmp;
	}

	free(arr);
	return 0;
}

如上,free释放了malloc开辟的动态内存

为什么需要释放内存

动态内存是由程序员开辟的,如果使用完之后不进行内存的释放,那么内存有可能导致堆积,内存泄露的风险,但是free不能对非动态内存进行释放,不然程序会报错


End

对于动态内存管理,我们就将到这里,关于动态内存管理,还有一个拓展点叫做柔性数组,这里我不在多讲啦,如果大家有兴趣可以自己百度一下!

相关文章:

  • ElementUI表格表头自定义添加checkbox,点击选中样式不生效
  • SQL-leetcode—1661. 每台机器的进程平均运行时间
  • 在 Flutter 实现下拉刷新、上拉加载更多和一键点击回到顶部的功能
  • Vulhub靶机 ActiveMQ 反序列化漏洞(CVE-2015-5254)(渗透测试详解)
  • webpack和vite打包原理及比较
  • PostgreSQL的学习心得和知识总结(一百六十八)|深入理解PostgreSQL数据库之PostgreSQL 规划器开发与调试(翻译)
  • HCIA项目实践--静态路由的综合实验
  • MySQL单表存多大的数据量比较合适
  • Flask使用JWT认证
  • 计数排序
  • 用pytorch实现一个简单的图片预测类别
  • 字符设备驱动开发
  • SpringBoot Bug 日志
  • python_excel批量插入图片
  • 数据结构——队列、哈希存储(2025.2.11)
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十二节】
  • Git 中的 author 和 committer 有什么区别
  • DeepSeek 从入门到精通学习指南,2025清华大学《DeepSeek从入门到精通》正式发布104页pdf版超全解析
  • 通过用户名和密码登录服务器有哪些方法
  • 基于语义语言的语义通信(SemCom)理论:语义编码、语义解码、CSED 及语言利用
  • 云南省安委会办公室:大理州安全生产形势比较严峻,事故总量一直居高不下
  • 央行最新报告:积极落地5月推出的一揽子金融政策,促进经济供需平衡、物价合理回升
  • 上海消防全面推行“检查码”,会同相关部门推行“综合查一次”
  • 海南省三亚市委原常委、秘书长黄兴武被“双开”
  • 美众议院通过法案将“墨西哥湾”更名为“美国湾”
  • 国家主席习近平同普京总统举行小范围会谈