C语言动态内存管理完全指南

分类:内存 · 2026-05-23 更新

1. 内存分配函数

C语言提供四个基本的动态内存管理函数,声明在 stdlib.h 中:

malloc - 分配原始内存

void *malloc(size_t size); /* 成功返回指针,失败返回 NULL */ int *arr = (int *)malloc(10 * sizeof(int)); if (arr == NULL) { /* 必须检查 */ perror("malloc"); exit(1); }

calloc - 分配并初始化为零

void *calloc(size_t nmemb, size_t size); /* 分配 nmemb 个元素,每个 size 字节,全部初始化为 0 */ int *arr = (int *)calloc(10, sizeof(int)); /* 等价于 malloc + memset(arr, 0, 10*sizeof(int)) */

realloc - 调整已分配内存大小

void *realloc(void *ptr, size_t size); /* 扩大数组容量 */ int *new_arr = (int *)realloc(arr, 20 * sizeof(int)); if (new_arr == NULL) { free(arr); /* 释放原内存 */ exit(1); } arr = new_arr;
realloc 可能返回新地址,必须使用返回值更新指针。

free - 释放内存

void free(void *ptr); /* 释放后应将指针置为 NULL,避免悬空指针 */ free(arr); arr = NULL;

2. 常见内存错误

/* 典型错误示例 */ /* 错误1: 未检查返回值 */ int *p = malloc(100); strcpy(p, "hello"); /* p 可能为 NULL */ /* 错误2: 内存泄漏 */ void leak(void) { int *p = malloc(1024); /* 忘记 free(p) */ } /* 错误3: 重复释放 */ free(p); free(p); /* 崩溃或未定义行为 */

3. 内存池实现

频繁调用 malloc/free 会产生内存碎片,内存池通过预分配大块内存,按需分配,提高性能。

/* 简单内存池实现 */ #include #include typedef struct MemPool { char *buffer; size_t capacity; size_t offset; } MemPool; MemPool *pool_create(size_t size) { MemPool *pool = malloc(sizeof(MemPool)); pool->buffer = malloc(size); pool->capacity = size; pool->offset = 0; return pool; } void *pool_alloc(MemPool *pool, size_t size) { if (pool->offset + size > pool->capacity) return NULL; void *ptr = pool->buffer + pool->offset; pool->offset += size; return ptr; } void pool_destroy(MemPool *pool) { free(pool->buffer); free(pool); }

4. 内存调试工具

/* 使用 Valgrind 检测内存泄漏 */ /* 编译:gcc -g -o prog prog.c */ /* 运行:valgrind --leak-check=full ./prog */
最佳实践:1) 始终检查 malloc 返回值;2) 遵循谁分配谁释放原则;3) 释放后立即置 NULL;4) 频繁分配场景考虑内存池。