[英]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)
有条件的跳跃或移动取决于未初始化的值
在与先前声明的双精度值进行比较的一行上(一个是模拟中生成的第一个值,另一个是我希望检查的元素,该值已确定)。
因此,我有两个问题:1.关于分段错误。 此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”,tx,ty,tz); fflush(stdout);
在上述行之前和之后。
首先,关于valgrind的关于未初始化值跳变的抱怨可能是正确的。 正确的C ++代码不会生成此警告。 (请注意,我在这里假设您已在valgrind中加载了默认排除项,因为可能存在一些位置标准库代码,这些代码设计为无论该值是否已初始化为合理值都可以正常工作,这可能是一个愚蠢的假设考虑到问题的其余部分的质量)一大缺点是您的结构中没有可初始化x,y,z值的构造函数。 在堆上分配的基本类型的值仍未初始化,并且将包含随机内存垃圾! 但是,崩溃的可能性不大。
第二件事,请考虑一下,std :: map是一种树。 假定从每个节点来看,较小的子项将保留,较大的子项将被保留。 因此,只要您更改内部会影响排序的内容(例如,进入索引并更改x,y或z),就可以说您在std :: map下面更改了键,却不知道该键,该节点就停留在它的位置突然出现错误,因为它违反了数据结构的基本假设! 在这种情况下,您要做的就是删除该条目,然后将其放回带有新索引的位置,这将使它进入集合中的正确位置。 这种不幸的事情在我身上发生了好几次。 我仍然不知道真正做到这一点的优雅方法,但至少在这里,可能和可能的原因。
当然,实际的错误不在您发布的代码中,并且甚至不清楚更改的位置和内容以及更改的数量,并且没有回溯到崩溃位置完全没有帮助。
永远不要忘记重建。
今天我发生了非常类似的事情。 奇怪的“随机”行为,在stl中崩溃...这表明这是一个构建问题-更改标头后未重新构建某些内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.