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

C++中int**二维数组返回后部分数值随机异常问题排查

问题根因

这是典型的悬空指针问题,核心错误是栈内存生命周期管理失当:

  • 你在switch case分支内定义的长度为10的int数组属于局部栈变量,内存分配在调用栈上,生命周期仅在当前case代码块范围内有效,离开分支后内存就会被系统回收复用。
  • 你将栈数组首地址赋值给new int*[10]申请的二级指针结构时,仅存储了内存地址,没有将数组内容拷贝到堆空间。
  • 函数内刚完成赋值就打印时,对应栈内存还没被覆写,因此输出完全符合预期;等函数返回回到main函数时,原栈内存已经被其他函数调用、临时变量操作覆写,自然会出现无规律的随机乱值。
修复方法

最小改动方案:为每行地图数据申请堆内存

保留原有二级指针结构,不要在case分支内直接把栈数组地址赋值给map指针,先给每一行申请独立的堆空间,再把栈数组的内容拷贝到堆上:

int** Process::get_story_map(int lvl) {
    int** map = new int*[10];
    // 预先为每一行申请堆内存
    for (int i = 0; i < 10; ++i) {
        map[i] = new int[10];
    }

    switch (lvl) {
        case 1: {
            // 临时栈数组仅做初始化数据源
            int row0[10] = {1,1,1,1,1,1,1,1,1,1};
            memcpy(map[0], row0, sizeof(int) * 10);
            // 其余9行按相同逻辑,要么逐元素赋值,要么用memcpy拷贝临时数组内容
            // ... 其余行填充逻辑
            break;
        }
        // 其余关卡分支逻辑一致
    }

    // 内部遍历打印逻辑
    return map;
}

注意:地图使用完后需要逐行调用delete[]释放,最后再释放二级指针本身,避免内存泄漏。

推荐方案:用连续一维数组存储瓦片数据

二级指针结构的二维数组内存不连续,CPU缓存命中率低,做瓦片遍历、碰撞检测时性能差,游戏开发中存储tilemap更常用一维数组模拟二维结构:

// 函数返回值改为int*,申请10*10长度的连续堆空间
int* Process::get_story_map(int lvl) {
    int* map = new int[10 * 10];
    switch (lvl) {
        case 1: {
            const int lvl1_data[100] = {
                1,1,1,1,1,1,1,1,1,1,
                1,0,0,0,0,0,0,0,0,1,
                // 其余地图数据
                1,1,1,1,1,1,1,1,1,1
            };
            memcpy(map, lvl1_data, sizeof(int) * 100);
            break;
        }
        // 其余关卡分支
    }
    return map;
}

访问第i行第j列的瓦片时,用map[i * 10 + j]的索引方式即可。

代码优化建议
  • 尽量不要手动管理裸指针内存,C++环境下优先用std::vector<std::vector<int>>或者一维的std::vector<int>存储瓦片数据,自动处理内存申请释放,从根源避免野指针、内存泄漏问题:
    std::vector<std::vector<int>> Process::get_story_map(int lvl) {
        std::vector<std::vector<int>> map(10, std::vector<int>(10, 0));
        // 直接通过map[i][j]赋值即可,无需手动管理内存
        return map;
    }
    
  • 固定关卡的静态瓦片数据可以定义为const static的类静态常量或全局常量,不用每次调用函数都重新申请内存、填充数据,运行效率更高。
  • 不要在switch case分支内写大段的数值填充逻辑,可以把不同关卡的地图数据抽成独立的常量数组,switch分支内只做数据拷贝逻辑,代码可读性和可维护性会明显提升。

内容的提问来源于stack exchange,提问作者cricciardi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:18:35