奇怪的分割错误和valgrind分析
weird segmentation fault and valgrind analysis
我有一个代码来运行膜的计算机模拟。我添加了一些小的修改,导致了最奇怪的分割错误。在我的代码中,我设置了一个地图:
struct index{
int x;
int y;
int z;
bool operator<(const index &b) const {
bool out = true;
if (x == b.x){
if (y == b.y){
out = z < b.z;
}else out = y < b.y;
}else out = x < b.x;
return out;
}
};
map<index,set<std::pair<int, int> > > tBoxes;
当我进行时出现分段故障
if (tBoxes.find(t) == tBoxes.end()) continue;
所以,当我通过valgrind运行代码时,我看到:1.当我第一次给地图赋值时,我就有了这个:
==26196== 6,568 (96 direct, 6,472 indirect) bytes in 1 blocks are definitely lost in loss record 86 of 145
==26196== at 0x4A0666E: operator new(unsigned long) (vg_replace_malloc.c:220)
==26196== by 0x4333C6: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::allocate(unsigned long, void const*) (new_allocator.h:88)
==26196== by 0x4333EB: std::_Rb_tree<membrane::index, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > >, std::_Select1st<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::_M_get_node() (stl_tree.h:358)
==26196== by 0x433407: std::_Rb_tree<membrane::index, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > >, std::_Select1st<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::_M_create_node(std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > const&) (stl_tree.h:367)
==26196== by 0x434474: std::_Rb_tree<membrane::index, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > >, std::_Select1st<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > const&) (stl_tree.h:819)
==26196== by 0x434919: std::_Rb_tree<membrane::index, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > >, std::_Select1st<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::insert_unique(std::_Rb_tree_iterator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > const&) (stl_tree.h:962)
==26196== by 0x434B52: std::map<membrane::index, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::insert(std::_Rb_tree_iterator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > >, std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > const&) (stl_map.h:420)
==26196== by 0x434C3B: std::map<membrane::index, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > >, std::less<membrane::index>, std::allocator<std::pair<membrane::index const, std::set<std::pair<int, int>, std::less<std::pair<int, int> >, std::allocator<std::pair<int, int> > > > > >::operator[](membrane::index const&) (stl_map.h:348)
- 在代码的某些后期阶段,需要注意:
条件跳转或移动取决于未初始化的值
- valgrind还有其他我目前不关注的信息。其中至少有一些与这两者有关
在与之前声明的双值(一个是模拟中生成的第一个值,另一个是我希望检查的元素,已确定)进行比较的行上
所以我有两个问题:1.关于分段故障。这个valgrind输出的含义是什么?怎么可能设置映射值是无效的呢。
- 关于条件跳转错误。怎么可能呢?有没有可能是valgrind把错误的位置解释错了
感谢您的帮助
编辑:
1.t
是一个合法定义的索引元素。我使用一个循环:
index t;
for (int i = mini; i <= maxi; i++){ //mini and maxi are previously defined
if (i < 0) t.x = i + P.boxNum; //P.boxNum is an integer, defined when I start the code
else if (i >= P.boxNum) t.x = i - P.boxNum;
else t.x = i;
for (int j = minj; j <= maxj; j++){//maxj and minj are previously defined
if (j < 0) t.y = j + P.boxNum;
else if (j >= P.boxNum) t.y =j - P. boxNum;
else t.y = j;
for(int k = mink; k <= maxk; k++){//mink and maxk are previously defined
if (k < 0) t.z = k + P.zBoxNum;
else if (k >= P.boxNum) t.z =k - P. zBoxNum;
else t.z = k;
if (tBoxes.find(t) == eBoxes.end()) continue;
//now I access tBoxes[t], this should be ok since if tBoxes[t] does not exist the loop should skip to the next value of k
}
}
}
我通过使用找到了分段故障的确切位置
printf("%i,%i,%i\n",t.x,t.y,t.z);fflush(stdout);
在上述行之前和之后。
首先,valgrind关于跳转到未初始化值的抱怨可能是正确的。正确的C++代码不会生成此警告。(注意,我在这里做了一个假设,在valgrind中加载了默认排除,因为无论值是否已初始化为正常值,都可以有标准库代码设计为正确工作的位置,考虑到问题其余部分的质量,这可能是一个愚蠢的假设)一个很大的失误是,你的结构中没有构造函数将初始化x、y、z值。堆上分配的基本类型的值保持未初始化状态,并且将包含随机内存垃圾!然而,这不太可能是你崩溃的原因。
第二件事,想想看,std::map是一种树。它假设在每个节点中,较小的子节点为左,较大的子节点则为右。因此,每当你更改内部影响排序的内容时,例如,你进入索引并更改x、y或z,也就是说,你从std::map下面更改了键,而节点却不知道,节点就留在了原来的位置,这突然就错了,因为它违反了数据结构的基本假设!在这种情况下,你要做的是删除条目,并将其放回一个新的索引中,这将使它位于集合中的正确位置。这种不幸的事情在我身上发生过好几次。我仍然不知道有什么真正优雅的方法可以做到这一点,但至少,在这里,可能和可能的原因。
当然,实际的错误不在你发布的代码中,甚至不清楚你在哪里、做了什么以及更改了多少,而且没有对崩溃位置的追溯也没有任何帮助。
永远不要忘记重建。
今天发生在我身上的事情非常相似。奇怪的"随机"行为,在stl中崩溃。。。结果显示这是一个构建问题——在头部更改后没有重建。
- valgrind-hellgrind与泄漏检查的结果不同
- (C++)分析树以计算返回错误值的简单算术表达式
- 函数复杂度分析
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 使用指针重新分析实体
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 额外分配valgrind
- 模板元编程 - 尝试实现维度分析
- 如何修复valgrind启动时的致命错误(与libc6-dbg和libc6-dbg:i386连接)
- 如何以静态代码分析友好的方式使用 #define 防护?
- Valgrind:可以处理更多可能丢失的字节吗?
- 如何在程序执行时查看Valgrind Massif输出(或其他堆分析器)?
- 为什么C++不支持对未初始化变量进行智能分析?
- 分析包含 NMEA 句子的日志文件C++
- Pisarze - 来自波兰奥林匹克信息学的数据分析任务
- 用valgrind分析c++字符内存泄漏
- 使用 valgrind C++对象初始化和堆使用情况分析
- 奇怪的分割错误和valgrind分析
- 一个bison/flex解析器的Valgrind memcheck结果分析
- STL设置内部映射,奇怪的seg故障和Valgrind分析