清华主页 - 清华新闻 - 综合时讯 - 正文

动态内存管理函数[数据结构]

动态内存管理。

  • 为什么会有动态内存管理?
  • 介绍动态内存函数。
    • 🎊malloc。
    • 补充:perror函数。
    • 🎊free。
    • 🎊calloc。
    • 🎊realloc。
  • 常见的动态内存错误。
    • 对空指针的解引操作。
    • 越界访问动态开放空间。
    • freee释放非动态开放内存。
    • 使用free释放动态开放内存的一部分。
    • 多次释放相同的动态内存。
    • 忘记释放动态开启内存(内存泄漏)

为什么会有动态内存管理?

之前,有两种方法可以开辟内存空间。一种是创建已知类型的变量。
例如:

int。a。=10。;//在栈空间打开四个字节。

向系统申请了四个字节的内存空间。(对于 int型󿀌它固定了四个字节。)。
另一种是,创建一个数组。
例如:

int。arr。[。10。]。;//在栈空间上开辟40个字节的连续空间。

向系统申请40个字节的内存空间。当这个数组打开空间࿰时c;没有办法改变它的大小。
创建数组,它的内存开放方式比较死板。

int。arr1。[。10。]。;int。arr2。[。100。]。;

当我们创建数组时,#xff0c;数组的大小将在一开始就指定。arr1的内存空间为40字节,可存放10个整形元素。arr2的内存空间为400字节,可存放100个整形元素。

但也许当我们使用数组ar1时,需要存储11个数组元素󿀌而。没有办法把它的边长。
为了尽可能地满足许多情况,创建一个大型数组ar2,但在实际使用过程中,我们可能只储存20个元素,而导致了。浪费内存空间。

因此,这种内存开放方式是固定的,不够灵活。 不仅仅是上述情况,有时我们需要的空间大小只有在程序运行时才能知道,然后数组在编译过程中无法满足开放空间的方式。 所以,我们需要学习。开放动态内存。

介绍动态内存函数。

malloc。
free。
calloc。
realloc。

🎊malloc。

malloc函数原型:

void。*。malloc。(。size_t。size。)。;

malloc声明在。stdlib.h。头文件中。
功能:
向内存申请此函数。连续可用。空间,并返回。指向该空间的指针。

  • 如果开放成功󿀌返回指向这个空间的指针。
  • 如果开启失败󿀌然后返回NULL指针。
  • 返回值的类型是 void* ,因此,malloc函数不知道开放空间的类型,具体用户在使用时要自行决定。

所以,必须检查malloc函数的返回值。

例如:
原来,我们用。数组。在。栈区。开辟内存空间:。

现在,我们在。堆区。动态开放相同大小的内存空间:

根据malloc函数的原型,我们需要传递参数,以。字节。单位内存。

malloc。(。40。)。//开辟了40个字节的内存空间。

然后,我们需要一个。指针p。为了指向这个区域开辟好的。连续的。内存空间。
但由于 malloc函数的返回值为。 void*。,即。无类型指针。,所以我们需要先做。强制转换。,将无类型指针转换为。整型指针。
所以,

int。*。p。=(。int。*。)。malloc。(。40。)。;

此时我们内存中开放空间的堆积空间,但是指向这个空间的指针是放在栈里的,也就是上面例子中的p指针。
如下图所示。
在这里插入图片描述

但是,正如我们上面提到的,我们只使用malloc函数。内存申请。开辟40个自己的连续空间,不一定开拓成功。所以我们需要使用它。指针p。进一步。检验。

如果成功开放󿀌访问:

malloc函数 申请的内存空间,但是当程序退出时,󿀌不会主动释放。,需要使用。free函数。来释放。

补充:perror函数。

perror函数(忘记打印输出函数)

这个博客:C语言peror函数详解。

🎊free。

C语言提供free函数󿼌专门用于制作。动态内存。的。释放和回收。的。
#xffff1a;

void。free。(。void。*。ptr。)。;

free函数也是第一个声明文件。中的。
用于释放free函数。动态开辟。的内存。

  • 如果参数ptr指向的空间不是动态开放的,那个free函数的行为是未定义的。
  • 如果参数ptr是NULL指针,那么函数什么都不做。

🎊calloc。

C语言还提供了一个叫calloc࿰的函数c;calloc函数也用于动态内存分配。
calloc函数原型:

void。*。calloc。(。size_t。num。,size_t。size。)。;

calloc函数为,为。num。个大小为。size。元素开辟空间,并将每个字节初始化为0。
与函数malloc函数的区别在于,在返回地址之前,calloc将应用程序的每个字节初始化为0。
即:

#。include。<stdio.h>#。include。int。main。(。)。{ 。test5。(。)。;while。(。1。)。;return。0;}。

例如,这个代码󿀌在主函数中,我调用test5()函数时,p指针在堆上申请空间,但是函数调用后󿀌这个test5()函数,局部变量指针p已被销毁。
但是,堆上开辟的100个空间仍在占用中。
此函数,我们找不到这个空间的地址,while(1)程序还在继续。
我们想用�但是我不知道这个空间的起始地址,所以我们不能用它。同样的,我们想释放#xff00c;我们仍然不能释放它。这就造成了。内存泄漏。
因此,只有在程序结束后󿀌自动释放。

2025-06-24 11:49:52

相关新闻

清华大学新闻中心版权所有,清华大学新闻网编辑部维护,电子信箱: news@tsinghua.edu.cn
Copyright 2001-2020 news.tsinghua.edu.cn. All rights reserved.