C语言中动态内存管理的完整指南和常见问题是什么?
动态内存分配函数:
-
malloc - 分配内存
cvoid *malloc(size_t size); // 分配指定字节数的内存 int *arr = (int*)malloc(10 * sizeof(int)); if (arr == NULL) { fprintf(stderr, "Memory allocation failed\n"); exit(1); } // 使用内存 for (int i = 0; i < 10; i++) { arr[i] = i * i; } // 释放内存 free(arr); -
calloc - 分配并初始化
cvoid *calloc(size_t num, size_t size); // 分配并初始化为零 int *arr = (int*)calloc(10, sizeof(int)); // 所有元素自动初始化为0 free(arr); -
realloc - 重新分配
cvoid *realloc(void *ptr, size_t size); int *arr = (int*)malloc(5 * sizeof(int)); // 扩展内存 int *new_arr = (int*)realloc(arr, 10 * sizeof(int)); if (new_arr == NULL) { free(arr); // 原内存仍然有效 exit(1); } arr = new_arr; free(arr); -
free - 释放内存
cvoid free(void *ptr); int *ptr = (int*)malloc(sizeof(int)); free(ptr); ptr = NULL; // 避免悬空指针
内存管理最佳实践:
-
检查分配结果
cvoid *ptr = malloc(size); if (ptr == NULL) { // 处理内存分配失败 return NULL; } -
避免内存泄漏
cvoid function_with_leak() { int *ptr = malloc(sizeof(int)); // 忘记 free(ptr) - 内存泄漏 } void correct_function() { int *ptr = malloc(sizeof(int)); if (ptr) { // 使用内存 free(ptr); } } -
防止悬空指针
cint *ptr = malloc(sizeof(int)); free(ptr); ptr = NULL; // 避免使用已释放的内存 // 错误示例 *ptr = 10; // 未定义行为 -
双重释放防护
cint *ptr = malloc(sizeof(int)); free(ptr); ptr = NULL; // 设置为NULL free(ptr); // free(NULL) 是安全的
常见问题和解决方案:
-
内存碎片
c// 问题:频繁分配和释放不同大小的内存 for (int i = 0; i < 1000; i++) { void *ptr = malloc(rand() % 1000); free(ptr); } // 解决:使用内存池或固定大小分配 -
缓冲区溢出
c// 危险 int *arr = malloc(10 * sizeof(int)); arr[10] = 100; // 越界访问 // 安全 int *arr = malloc(10 * sizeof(int)); if (index < 10) { arr[index] = value; } -
野指针
cint *ptr; // 未初始化 *ptr = 10; // 未定义行为 // 正确做法 int *ptr = NULL; ptr = malloc(sizeof(int)); if (ptr) { *ptr = 10; free(ptr); ptr = NULL; }
高级技巧:
-
自定义内存分配器
cvoid* my_malloc(size_t size) { void *ptr = malloc(size); if (ptr) { memset(ptr, 0, size); // 清零 } return ptr; } -
内存调试
c#ifdef DEBUG void *debug_malloc(size_t size, const char *file, int line) { void *ptr = malloc(size); printf("Allocated %zu bytes at %p (%s:%d)\n", size, ptr, file, line); return ptr; } #define MALLOC(size) debug_malloc(size, __FILE__, __LINE__) #else #define MALLOC(size) malloc(size) #endif