前言
malloc()
、calloc()
、realloc()
都是 C 语言中的动态内存分配函数,它们的作用都是在堆上分配内存,但它们的行为和用途有所不同。下面详细介绍它们的区别。
1. malloc()
(Memory Allocation 内存分配)
malloc()
用于分配一块指定大小的内存区域。分配的内存内容是未初始化的,意味着它的内容是随机的(不确定的)。
语法:
void* malloc(size_t size);
size
:请求分配的内存块的字节数。- 返回值:返回指向分配内存的指针,如果分配失败,则返回
NULL
。
特点:
- 分配的内存大小是通过
size
参数指定的。 - 内存未初始化,内存的内容是随机的(即不确定的垃圾值)。
- 返回
void*
,需要强制类型转换成目标类型指针。
示例:
int* ptr = (int*)malloc(10 * sizeof(int)); // 分配 10 个 int 大小的内存
if (ptr == NULL) {
printf("内存分配失败\n");
} else {
// 使用分配的内存
}
2. calloc()
(Contiguous Allocation 连续分配)
calloc()
用于分配一个指定数量的内存块,并且将这块内存初始化为 0。它的功能类似于 malloc()
,但它还会初始化分配的内存。
语法:
void* calloc(size_t num, size_t size);
num
:要分配的元素的数量。size
:每个元素的字节大小。- 返回值:返回指向分配内存的指针,如果分配失败,则返回
NULL
。
特点:
- 分配的内存块大小是
num * size
。 - 内存初始化为 0,确保分配的内存不会包含垃圾值。
- 返回
void*
,需要强制类型转换成目标类型指针。
示例:
int* ptr = (int*)calloc(10, sizeof(int)); // 分配 10 个 int 大小的内存并初始化为 0
if (ptr == NULL) {
printf("内存分配失败\n");
} else {
// 使用分配的内存,所有元素初始为 0
}
3. realloc()
(Reallocation 重新分配)
realloc()
用于重新调整已经分配的内存块的大小。它可以增加或减少内存的大小。如果内存地址发生变化(例如扩展后的内存空间无法容纳在原来的位置),realloc()
会返回一个新的指向内存的指针。如果无法扩展内存,realloc()
返回 NULL
,并且原始内存块保持不变。
语法:
void* realloc(void* ptr, size_t new_size);
ptr
:指向已分配内存块的指针。new_size
:请求的新内存大小(字节数)。- 返回值:返回指向重新分配后内存的指针。如果分配失败,返回
NULL
,原内存块保持不变。
特点:
realloc()
会根据new_size
调整内存块的大小。- 扩展内存时,如果原内存块不能容纳更多空间,
realloc()
会返回一个新的指针。 - 缩小内存时,
realloc()
会减少内存块的大小,并保留原有的数据。 - 如果
realloc()
失败,返回NULL
,原来的内存不会被释放。
示例:
int* ptr = (int*)malloc(10 * sizeof(int)); // 初始分配 10 个 int 大小的内存
if (ptr == NULL) {
printf("内存分配失败\n");
}
// 重新调整内存块大小,增加到 20 个 int 大小
ptr = (int*)realloc(ptr, 20 * sizeof(int));
if (ptr == NULL) {
printf("内存重新分配失败\n");
} else {
// 使用新的内存块
}
4. 三者的区别总结
特性 | malloc() |
calloc() |
realloc() |
---|---|---|---|
功能 | 分配一块指定大小的内存块 | 分配并初始化为 0 的内存块 | 重新调整已经分配内存的大小(增加或减少) |
初始化 | 不初始化内存,内存内容是垃圾值 | 将分配的内存初始化为 0 | 新分配的内存会初始化为 0(仅当扩展时有新内存分配) |
返回值 | 返回 void* 类型,需强制转换 |
返回 void* 类型,需强制转换 |
返回重新分配后的指针,若失败则返回 NULL |
用法 | 用于分配已知大小的内存块 | 用于分配已知大小的内存并初始化为 0 | 用于调整已分配内存的大小 |
内存管理 | 不会释放内存,需手动释放 | 不会释放内存,需手动释放 | 返回新的内存块,若失败则返回 NULL ,不会释放原内存 |
适用场景 | 仅需要分配内存,但不关心初始化内容 | 需要初始化内存为 0 | 需要调整原内存块的大小 |
5. 总结
malloc()
:分配内存,但不初始化内容,适用于只需要分配内存而不关心初值的情况。calloc()
:分配并初始化内存,适用于需要内存初始化为零的情况。realloc()
:重新调整内存块的大小,适用于已经分配内存后需要扩大或缩小内存的情况。
在我们写c程序时,选择合适的内存分配函数有助于提高程序的效率和安全性。