动态内存管理。
- 为什么会有动态内存管理?
- 介绍动态内存函数。
- 🎊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;我们仍然不能释放它。这就造成了。内存泄漏。。
因此,只有在程序结束后自动释放。