为何向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
原因分析
- vector越界访问:
mapLayerCollision是二维vector,但初始化时为空,mapLayerCollision[row]在row=0时会访问不存在的元素,属于未定义行为。 - 未定义行为的连锁破坏:未定义行为会导致程序出现任何诡异结果,包括看似不相关的代码异常。越界访问会破坏内存,可能覆盖
stringstream内部的缓冲区数据,或干扰程序执行流程,最终导致打印乱码。 - 注释时正常的原因:注释插入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
相关产品推荐
相关产品推荐

