You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

崩溃原因分析

  1. 内存分配与实际需求不匹配:

    • 代码中用rows*rows计算malloc的内存大小,但二维数组的总元素数应为rows*cols。当输入数组不是正方形(rows != cols)时,要么分配的内存不足,导致写入数组时越界;要么分配过多内存,但outsz设置为错误的rows*rows,测试框架会错误地访问未初始化的内存区域。
    • 内存越界会破坏堆的元数据结构,当测试框架调用free()释放result指针时,就会触发munmap_chunk(): invalid pointer错误。
  2. outsz值错误:

    • 代码中将*outsz设置为rows*rows,这与实际输出数组的大小rows*cols不符。当修正outsz为正确值时,测试框架会尝试访问所有rows*cols个元素,但之前malloc的内存不足,导致越界访问,最终触发崩溃。

修复方案

  1. 修正内存分配大小:
    将malloc的参数改为rows*cols * sizeof(int)(显式写出sizeof(int)更清晰,避免因类型变更导致的错误),确保分配的内存足够容纳所有元素:

    int* result = malloc(rows * cols * sizeof(int));
    
  2. 修正outsz的值:
    将*outsz设置为正确的总元素数rows*cols:

    *outsz = rows * cols;
    
  3. 适配矩形数组的遍历逻辑(可选):
    原代码的遍历逻辑仅适用于正方形数组(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:34:55