为什么std::set<std::pair<int,int>>插入坐标转换的行列值会出现重复?
问题成因分析
std::set 底层采用红黑树实现,插入新元素的逻辑不会修改任何已存储的旧元素,你观察到的「插入第k个元素后所有元素都变成重复值」是典型的内存异常或者观测错误导致的现象,具体根因可以从以下几个方向排查:
- 首先排除观测错误:部分IDE的调试器对
std::set<std::pair<int,int>>的内存预览存在解析bug,不要直接依赖调试器的变量窗口展示结果,你可以新增一段遍历代码打印set的所有元素,确认是否真的出现了元素被修改的情况:
for (auto& p : occupiedCellList) { std::cout << "row: " << p.first << ", col: " << p.second << std::endl; }
- 排查coordPairs填充逻辑的越界问题:如果你的coordPairs初始化大小为N,但实际写入时超过了N个元素,溢出的堆/栈内存会直接破坏相邻的
occupiedCellList的内部节点指针结构,导致所有节点指针都指向同一个pair内存地址,最终表现为所有元素值相同。 - 排查网格计算变量的异常修改:检查
ymin、xmin、cellSizeInMeters三个变量是否在循环过程中被意外改写,比如被野指针修改、或者其他分支逻辑错误赋值,会导致后续所有row、col的计算结果都相同,看起来就像旧元素被替换成了新值,实际只是新插入的都是重复值。 - 浮点数精度导致的重复插入问题:如果你实际遇到的是set中出现了本应该唯一的重复pair(而非所有元素变成同一个值),大概率是浮点计算的精度误差导致,比如坐标值刚好落在网格边界时,计算结果会出现
1.0 - 1e-15这类极小的偏差,floor后得到的整数和预期不符,可以添加极小的epsilon偏移修正计算逻辑:
const double eps = 1e-6; int row = static_cast<int>(floor((y - ymin) / cellSizeInMeters + eps)); int col = static_cast<int>(floor((x - xmin) / cellSizeInMeters + eps));
内容的提问来源于stack exchange,提问作者lounice
相关产品推荐
相关产品推荐

