繁体   English   中英

怪异的分割错误和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)
  1. 在代码的后期,请注意:

有条件的跳跃或移动取决于未初始化的值

  1. 还有,valgrind的其他消息,我目前不关注。 至少其中一些与这两个有关。

在与先前声明的双精度值进行比较的一行上(一个是模拟中生成的第一个值,另一个是我希望检查的元素,该值已确定)。

因此,我有两个问题:1.关于分段错误。 此valgrind输出的含义是什么? 设置映射值怎么可能是无效的。

  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
    }
  }
}
  1. 我通过使用以下方法找到了分段错误的确切位置:

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM