munmap_chunk(): invalid pointer错误分析及蜗牛排序C代码修复
蜗牛排序实现中的munmap_chunk()错误分析与修复
问题背景
我正在解决蜗牛排序问题,需求是按蜗牛爬行的顺序遍历二维数组元素,示例如下:
array = [[1,2,3], [4,5,6], [7,8,9]] snail(array) #=> [1,2,3,6,9,8,7,4,5]
当前的C语言实现能输出正确的数组,但将outsz设置为正确的输出数组大小时,测试会崩溃并抛出munmap_chunk(): invalid pointer错误;若设置错误的outsz值则不会崩溃,但测试用例无法通过。已知该错误与free()操作相关,需要明确崩溃原因及修复方案。
现有实现代码
#include <stdlib.h> int *snail(size_t *outsz, const int **mx, size_t rows, size_t cols) { int k = 0; int* result = (int*)malloc(rows*rows); int x = 0; int y = 0; int n = rows; while (n > 0) { for (int i = x; i < x + n; ++i){ result[k] = mx[y][i]; k++; } n--; y++; for (int i = y; i < y + n; ++i){ result[k] = mx[i][x + n]; k++; } for (int i = x + n - 1; i >= x; --i){ result[k] = mx[y + n - 1][i]; k++; } n--; for (int i = y + n - 1; i >= y; --i){ result[k] = mx[i][x]; k++; } x++; } *outsz = rows*rows; return result; }
崩溃原因分析
内存分配与实际需求不匹配:
- 代码中用
rows*rows计算malloc的内存大小,但二维数组的总元素数应为rows*cols。当输入数组不是正方形(rows != cols)时,要么分配的内存不足,导致写入数组时越界;要么分配过多内存,但outsz设置为错误的rows*rows,测试框架会错误地访问未初始化的内存区域。 - 内存越界会破坏堆的元数据结构,当测试框架调用
free()释放result指针时,就会触发munmap_chunk(): invalid pointer错误。
- 代码中用
outsz值错误:
- 代码中将
*outsz设置为rows*rows,这与实际输出数组的大小rows*cols不符。当修正outsz为正确值时,测试框架会尝试访问所有rows*cols个元素,但之前malloc的内存不足,导致越界访问,最终触发崩溃。
- 代码中将
修复方案
修正内存分配大小:
将malloc的参数改为rows*cols * sizeof(int)(显式写出sizeof(int)更清晰,避免因类型变更导致的错误),确保分配的内存足够容纳所有元素:int* result = malloc(rows * cols * sizeof(int));修正outsz的值:
将*outsz设置为正确的总元素数rows*cols:*outsz = rows * cols;适配矩形数组的遍历逻辑(可选):
原代码的遍历逻辑仅适用于正方形数组(rows == cols),如果需要支持矩形数组,需要调整循环中的剩余行/列计数逻辑。修复后的逻辑会分别跟踪剩余的行和列数量,避免因行/列数不等导致的遍历遗漏或越界:
修复后的完整代码:
#include <stdlib.h> int *snail(size_t *outsz, const int **mx, size_t rows, size_t cols) { int k = 0; int* result = malloc(rows * cols * sizeof(int)); if (!result) { // 增加内存分配失败的判断,避免空指针操作 *outsz = 0; return NULL; } int x = 0; int y = 0; int remaining_rows = rows; int remaining_cols = cols; while (remaining_rows > 0 && remaining_cols > 0) { // 从左到右遍历顶部行 for (int i = x; i < x + remaining_cols; ++i){ result[k++] = mx[y][i]; } y++; remaining_rows--; if (remaining_rows == 0) break; // 从上到下遍历右侧列 for (int i = y; i < y + remaining_rows; ++i){ result[k++] = mx[i][x + remaining_cols - 1]; } remaining_cols--; if (remaining_cols == 0) break; // 从右到左遍历底部行 for (int i = x + remaining_cols - 1; i >= x; --i){ result[k++] = mx[y + remaining_rows - 1][i]; } remaining_rows--; if (remaining_rows == 0) break; // 从下到上遍历左侧列 for (int i = y + remaining_rows - 1; i >= y; --i){ result[k++] = mx[i][x]; } remaining_cols--; x++; } *outsz = rows * cols; return result; }
内容的提问来源于stack exchange,提问作者FirstTree
相关产品推荐
相关产品推荐

