C语言动态内存函数解析:malloc、calloc、free
malloc 函数
功能:分配指定大小的内存块
原型:
void* malloc(size_t size);
特点:
- 分配
size
字节的未初始化内存 - 返回指向分配内存的指针,失败返回NULL
- 不会自动初始化内存内容(内容是随机的)
- 需要手动释放内存
示例:
int *arr = (int*)malloc(10 * sizeof(int));
if (arr == NULL) {
// 处理内存分配失败
}
// 使用内存...
free(arr); // 使用完毕后释放
calloc 函数
功能:分配并初始化内存块
原型:
void* calloc(size_t num, size_t size);
特点:
- 分配
num * size
字节的内存 - 内存内容自动初始化为0
- 返回指向分配内存的指针,失败返回NULL
- 需要手动释放内存
示例:
int *arr = (int*)calloc(10, sizeof(int));
if (arr == NULL) {
// 处理内存分配失败
}
// arr指向的内存已初始化为0
free(arr);
free 函数
功能:释放之前分配的内存
原型:
void free(void* ptr);
特点:
- 释放由malloc、calloc或realloc分配的内存
- 传入NULL指针是安全的(不做任何操作)
- 释放后指针变为悬垂指针(应设为NULL)
- 不能重复释放同一块内存
示例:
int *ptr = (int*)malloc(sizeof(int));
*ptr = 100;
free(ptr);
ptr = NULL; // 避免悬垂指针
对比malloc和calloc
| 特性 | malloc | calloc |
|------------|----------------------|----------------------|
| 初始化 | 不初始化 | 初始化为0 |
| 参数 | 总字节数 | 元素个数和单个元素大小|
| 性能 | 略快 | 稍慢(因为要初始化) |
| 适用场景 | 需要手动初始化时 | 需要零初始化时 |
使用注意事项
- 检查返回值:分配失败时返回NULL,必须检查
- 类型转换:在C++中需要类型转换,C中可选但推荐
- 内存泄漏:分配后必须释放,避免内存泄漏
- 悬垂指针:释放后指针应设为NULL
- 野指针:不要访问已释放的内存
- 大小计算:使用sizeof计算类型大小,避免硬编码
常见错误
// 错误1:忘记检查返回值
int *p = malloc(1000000000); // 可能失败
// 错误2:忘记释放内存
void func() {
char *str = malloc(100);
// 使用后忘记free
}
// 错误3:访问已释放内存
int *p = malloc(sizeof(int));
free(p);
*p = 10; // 未定义行为
// 错误4:重复释放
free(p);
free(p); // 错误
正确使用动态内存管理是C/C++编程中的重要技能,合理使用可以大大提高程序的灵活性和效率。
(本文来源:nzw6.com)