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

为何向vector插入内容后stringstream出现乱码?如何修复?

问题分析:stringstream值异常与vector插入的关联

问题背景

当前代码中,注释掉mapLayerCollision[row].push_back(std::stoi(value.str()));时,所有打印的stringstream内容正常;但取消注释后,哪怕是插入前的打印语句(如std::cout << "Value AFTER: " << value.str() << std::endl;)也会出现乱码,且乱码语句位于插入代码之前。

核心代码

void someFunc {
    std::stringstream value;
    std::vector<std::vector<int>> mapLayerCollision;
    int row = 0;

    for(int i = 0; i < gid_list.length(); i++) {
        if(gid_list[i] == ',') {
            value.str("");
            int j = 1;
            while (gid_list[i-j] != ',' and i - j > 0) {
                std::cout << gid_list[i-j] << " | ";
                j++;
                std::cout << gid_list[i-j] << std::endl;
            }
            j--;
            value.str("");
            std::cout << "j: " << j << std::endl;
            while (j > 0) {
                std::cout << "Inserting: " << gid_list[i-j] << std::endl;
                value << gid_list[i-j];
                std::cout << "Value AFTER: " << value.str() << std::endl;
                j--;
            }
            std::cout << "Putting into vector: " << std::stoi(value.str()) << std::endl;
            //mapLayerCollision[row].push_back(std::stoi(value.str()));
            value.str("");
        }
        
        else if(gid_list[i] == '\n') {
            value.str("");
            int j = 1;
            while (gid_list[i-j] != ',') {
                j++;
            }
            j--;
            value.str("");
            while (j > 0) {
                value << gid_list[i-j];
                j--;
            }
            std::cout << "Putting into vector: " << value.str() << std::endl;
            //mapLayerCollision[row].push_back(std::stoi(value.str()));
            value.str("");
            row++;
        }
    }
}

gid_list内容

79,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,455,70,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,195,210,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,274,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,323,338,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,387,402,0,0,0,0,0,259,
274,0,0,346,0,0,0,350,0,0,0,0,0,0,0,0,0,451,466,0,0,0,0,0,259,
274,0,0,410,0,0,0,414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
338,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
402,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
338,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,195,210,0,0,0,0,0,0,259,
402,0,0,0,0,195,198,199,200,210,0,0,0,0,0,0,451,466,0,0,0,0,0,0,259,
274,0,0,0,0,387,264,264,264,402,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,451,455,456,457,466,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,259,
212,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,216,
73,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,199,200,201,199,200,201,76

原因分析

  1. vector越界访问:mapLayerCollision是二维vector,但初始化时为空,mapLayerCollision[row]在row=0时会访问不存在的元素,属于未定义行为。
  2. 未定义行为的连锁破坏:未定义行为会导致程序出现任何诡异结果,包括看似不相关的代码异常。越界访问会破坏内存,可能覆盖stringstream内部的缓冲区数据,或干扰程序执行流程,最终导致打印乱码。
  3. 注释时正常的原因:注释插入vector的代码后,没有触发越界访问的未定义行为,内存未被破坏,stringstream的内容和打印自然正常。

修复方案

核心是确保访问二维vector的行之前,该行已被创建,同时修正循环逻辑的错误:

修正后的代码

void someFunc {
    std::stringstream value;
    std::vector<std::vector<int>> mapLayerCollision;
    int row = 0;
    // 提前创建第一行
    mapLayerCollision.emplace_back();

    for(int i = 0; i < gid_list.length(); i++) {
        if(gid_list[i] == ',') {
            value.str("");
            int j = 1;
            // 修正循环条件:避免跳过第一个元素
            while (i - j >= 0 && gid_list[i-j] != ',') {
                j++;
            }
            j--;
            value.str("");
            std::cout << "j: " << j << std::endl;
            while (j > 0) {
                value << gid_list[i-j];
                j--;
            }
            int num = std::stoi(value.str());
            std::cout << "Putting into vector: " << num << std::endl;
            mapLayerCollision[row].push_back(num);
            value.str("");
        }
        
        else if(gid_list[i] == '\n') {
            value.str("");
            int j = 1;
            while (i - j >= 0 && gid_list[i-j] != ',') {
                j++;
            }
            j--;
            value.str("");
            while (j > 0) {
                value << gid_list[i-j];
                j--;
            }
            int num = std::stoi(value.str());
            std::cout << "Putting into vector: " << num << std::endl;
            mapLayerCollision[row].push_back(num);
            value.str("");
            // 创建新行用于下一组数据
            mapLayerCollision.emplace_back();
            row++;
        }
    }
    // 移除最后可能存在的空行
    if(!mapLayerCollision.empty() && mapLayerCollision.back().empty()) {
        mapLayerCollision.pop_back();
    }
}

关键优化点

  • 修正了处理逗号的循环条件,避免跳过第一个元素;
  • 提前创建vector的行,确保mapLayerCollision[row]访问合法;
  • 将value.str()转成int后存储,避免多次调用std::stoi,提升效率同时减少重复解析的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:24:18