C语言malloc类函数详解
在 C 语言中,动态内存管理主要依赖于标准库中的一组函数。以下是 malloc
及其同类函数的详细说明:
1. 基础动态内存分配函数
(1) malloc
void* malloc(size_t size);
-
功能:分配指定字节数的未初始化内存。
-
特点:
-
内存内容未初始化(可能包含随机值)。
-
分配失败时返回
NULL
。
-
-
示例:
int *arr = (int*)malloc(10 * sizeof(int)); // 分配10个int的空间
(2) calloc
void* calloc(size_t num, size_t size);
-
功能:为
num
个元素分配连续内存,并将内存初始化为零。 -
特点:
-
内存内容初始化为全零。
-
适合分配数组或结构体数组。
-
-
示例:
int *arr = (int*)calloc(10, sizeof(int)); // 分配并初始化10个int
(3) realloc
void* realloc(void* ptr, size_t new_size);
-
功能:调整已分配内存块的大小。
-
特点:
-
ptr
必须是malloc
/calloc
/realloc
返回的指针。 -
new_size
为 0 时等效于free(ptr)
。 -
可能返回新地址,需重新接收返回值。
-
-
示例:
arr = (int*)realloc(arr, 20 * sizeof(int)); // 扩展为20个int
(4) free
void free(void* ptr);
-
功能:释放动态分配的内存。
-
注意:
-
只能释放由
malloc
/calloc
/realloc
分配的内存。 -
释放后应将指针置为
NULL
,避免悬空指针。
free(arr); arr = NULL; // 防止误用
-
2. 高级内存管理函数
(1) aligned_alloc
(C11 引入)
void* aligned_alloc(size_t alignment, size_t size);
-
功能:分配对齐到
alignment
字节的内存。 -
要求:
-
size
必须是alignment
的整数倍。
-
-
示例:
int *arr = (int*)aligned_alloc(64, 1024); // 64字节对齐
(2) valloc
(已废弃,POSIX 标准)
void* valloc(size_t size);
-
功能:分配页面对齐的内存(类似
aligned_alloc
,但对齐到页面大小)。 -
注意:已被
aligned_alloc
或posix_memalign
替代。
3. 非标准扩展函数
(1) alloca
(栈上分配,非标准)
void* alloca(size_t size);
-
功能:在栈上分配内存(函数返回时自动释放)。
-
风险:
-
可能导致栈溢出。
-
不可跨函数使用。
-
-
示例:
int *arr = (int*)alloca(10 * sizeof(int)); // 栈内存,无需手动释放
(2) memalign
(已过时)
void* memalign(size_t alignment, size_t size);
-
功能:类似
aligned_alloc
,但不受 C 标准约束。 -
替代:优先使用
aligned_alloc
。
4. 调试工具函数
(1) malloc_usable_size
(GNU 扩展)
size_t malloc_usable_size(void* ptr);
-
功能:查询实际分配的内存块大小(可能大于请求值)。
-
示例:
size_t real_size = malloc_usable_size(arr); // 实际分配的内存大小
5. 内存操作函数
(1) memset
void* memset(void* ptr, int value, size_t num);
-
功能:将内存块填充为指定值。
-
常用场景:初始化内存(替代
calloc
的部分功能)。
(2) memcpy
/ memmove
void* memcpy(void* dest, const void* src, size_t num);
void* memmove(void* dest, const void* src, size_t num);
-
功能:复制内存内容。
-
区别:
memmove
可处理内存重叠区域。
使用注意事项
-
检查返回值:
malloc
/calloc
/realloc
可能返回NULL
,需检查分配是否成功。if (arr == NULL) { fprintf(stderr, "内存分配失败!"); exit(EXIT_FAILURE); }
-
避免内存泄漏:
-
确保每个
malloc
/calloc
都有对应的free
。 -
使用工具(如 Valgrind)检测内存泄漏。
-
-
防止悬空指针:
free(ptr); ptr = NULL; // 释放后置空
-
对齐要求:
-
处理 SIMD 指令或硬件访问时,使用
aligned_alloc
确保内存对齐。
-
总结
函数 | 用途 | 初始化 | 内存来源 |
---|---|---|---|
malloc | 分配未初始化内存 | 否 | 堆 |
calloc | 分配并清零内存 | 是 | 堆 |
realloc | 调整已分配内存大小 | 保留数据 | 堆 |
free | 释放内存 | - | 堆 |
aligned_alloc | 对齐内存分配 | 否 | 堆 |
alloca | 栈上分配(自动释放) | 否 | 栈 |
根据需求选择合适的函数,并始终遵循谁分配谁释放的原则!