C 库中的 malloc() 函数及其示例

C 语言中的 malloc 是什么?
malloc() 函数代表内存分配。它是一个用于动态分配内存块的函数。它保留指定大小的内存空间并返回指向内存位置的空指针。返回的指针通常是 void 类型。这意味着我们可以将 malloc 函数分配给任何指针。
句法
ptr = (cast_type *) malloc (byte_size);
在这里,
- ptr 是 cast_type 的指针。
- malloc 函数返回指向分配的 byte_size 内存的指针。
Example: ptr = (int *) malloc (50)
当该语句执行成功后,会保留50字节的内存空间,保留空间第一个字节的地址赋给int类型的指针ptr。
考虑 malloc 实现的另一个例子:
#include <stdlib.h> int main(){ int *ptr; ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */ if (ptr != NULL) { *(ptr + 5) = 480; /* assign 480 to sixth integer */ printf("Value of the 6th integer is %d",*(ptr + 5)); } }
输出:
Value of the 6th integer is 480
请注意,这里使用了 sizeof(*ptr) 而不是 sizeof(int),目的是为了在稍后将 *ptr 声明强制转换为不同的数据类型时,使代码更加健壮。
如果内存不足,分配可能会失败。在这种情况下,它会返回一个 NULL 指针。因此,您应该包含代码来检查 NULL 指针。
请记住,分配的内存是连续的,可以将其视为数组。我们可以使用 指针 建议使用加号 (+) 而不是方括号 [ ] 来访问数组元素,因为使用加号 (++) 或加号 (+=) 会改变指针存储的地址。
Malloc 函数还可以用于字符数据类型以及结构等复杂数据类型。
为什么在C语言中使用malloc()?
静态数组和普通变量在程序编译时就固定了它们的大小,这会导致在实际需求较小时浪费空间,而在实际需求较大时直接导致程序崩溃。malloc() 通过在运行时请求内存来解决这个问题,因此程序可以根据接收到的数据量精确地分配缓冲区大小。这种运行时灵活性是内存分配的核心所在。 动态内存分配 在 C。
在几种常见情况下,使用 malloc() 进行动态分配是正确的选择:
- 在程序运行之前,输入量是未知的,例如读取文件或用户提供的列表。
- 需要大块内存才能分配有限的内存,因为 malloc() 是从更大的堆中分配的,这会导致有限的栈溢出。
- 数据的生命周期必须长于创建它的函数,因为堆内存会一直存在,直到被显式释放为止。
- 程序运行时,结构体和数组需要增长或缩小。
由于保留的数据块是以指针的形式返回的,因此可以在函数之间以低成本传递,而无需复制底层数据。
如何释放 malloc() 分配的内存
malloc() 函数分配的内存位于堆上,不会自动释放。当程序不断分配内存而不释放时,它会逐渐耗尽所有可用内存,这种缺陷被称为内存泄漏。free() 函数会将已分配的内存块释放回系统,以便系统可以重新利用这些空间。
free() 函数接受一个参数,即 malloc() 返回的指针,并一次性释放整个内存块:
int *ptr; ptr = malloc(10 * sizeof(int)); if (ptr != NULL) { /* use the allocated memory here */ free(ptr); /* release the block */ ptr = NULL; /* avoid a dangling pointer */ }
请遵循以下规则安全地管理动态内存:
- 对于每个成功的 malloc(),都应调用 free() 一次;对同一个内存块释放两次会导致未定义行为。
- 释放指针后将其设置为 NULL,以防止其被重新用作悬空指针。
- 永远不要使用 free() 释放 malloc() 没有返回的指针,包括通过指针运算移位的指针。
- 在指针超出作用域之前,每次内存分配都必须与相应的内存释放相匹配。
记ping 内存分配和释放的平衡是 C 语言中手动内存管理的核心原则,它可以防止因重复使用已释放的内存而导致的内存泄漏和崩溃。
malloc() 与 calloc():主要区别
malloc() 和 调用() 两者都会分配堆内存,但它们的参数和处理方式有所不同。malloc() 接受一个参数,即总字节数,并且不会初始化内存块的内容,因此在程序写入之前,该内存块会包含不可预测的垃圾值。calloc() 接受两个参数,即元素的数量和每个元素的大小,并在返回指针之前将每个字节清零。
实际上的区别主要体现在以下三点:
- 初始化:calloc() 会将内存清零,而 malloc() 不会,因此当值无论如何都会被覆盖时,malloc() 的速度会稍微快一些。
- 论点:你写 malloc(n * size) 但 calloc(n, size) 来保留同一个数组。
- 使用场景:当需要干净、零化的数据块时,选择 calloc();当优先考虑速度并且需要手动处理初始化时,选择 malloc()。
这两个函数都在 stdlib.h 中声明,失败时都返回 void 指针或 NULL,并且都使用相同的 free() 函数释放内存。

