如何处理数组C++中的分段错误

How to handle segmentation fault in an array C++

本文关键字:C++ 分段 错误 数组 何处理 处理      更新时间:2023-10-16

我正在创建一个程序,该程序基于跟踪顶点信息以及从一个顶点到另一个顶点的最短路径的集合和表格来查找从一个节点到另一顶点的最长路径。这是使用数组而不是链表创建的。

//--------------------------------------------------------------------------
// 'updatepaths' uses the newest vertex which was added to the Set to modify
//  the distances of the remaining vertices (if smaller)
//  in addition to the newly added vertex, it uses the Set, the Vertexinfo
//  and the Shortpath tables
//--------------------------------------------------------------------------
void Paths::updatepaths(int addnode)
{    
  if (done.in(addnode)) //done is a set instance, checks if the value is in the set
  {
    for (int i = 0; i<VERTICES; i++)
    {
      if (shortpath[edgedata[addnode].path[i].vertexto].distance > edgedata[addnode].path[i].weight) //HERE IS THE ISSUE
      {
        shortpath[edgedata[addnode].path[i].vertexto].distance = edgedata[addnode].path[i].weight;
        shortpath[edgedata[addnode].path[i].vertexto].via = addnode;            
      }
    }
  }     
}

我意识到代码很难阅读,但这是我能想到的唯一比较顶点距离的方法——问题是,在if语句中,有时它会尝试比较数组中不存在的值。

例如,edgedata[addnode].path[0].weight可能包含NO VALUE,因此我的程序会抛出访问违规(分段错误)。我尝试在if语句中设置edgedata[addnode].path[i].weight != NULL和0,但在算术过程中不能使用NULL,如果它不存在,就永远不会是0。

我应该如何制作它,这样它就不会试图比较不存在的值?谢谢你的帮助。

如果您的逻辑经常碰到NULL对象,代码中可能会出现更大的设计或实现问题,但要解决眼前的问题,最简单的方法是使用std::array<>::at()而不是std::array<>::operator[],并捕获它可以生成的out_of_range异常:

try {
  if (shortpath.at(edgedata.at(addnode).path.at(i).vertexto).distance >
      edgedata.at(addnode).path.at(i).weight)
  {
    shortpath.at(edgedata.at(addnode).path.at(i).vertexto).distance =
      edgedata.at(addnode).path.at(i).weight;
    shortpath.at(edgedata.at(addnode).path.at(i).vertexto).via = addnode;
  }
}
catch (std::out_of_range const &oor) {
  std::cerr << "Out of Range error: " << oor.what() << std::endl;
}

或者,您可以在if语句中沿着以下行缩短检查(我可能错过了一两次检查,所以请注意):

if ((edgedata.size() >= addnode)
 && (edgedata[addnode].path.size() >= i)
 && (shortpath.size() >= edgedata[addnode].path[i].vertexto)
 && (shortpath[edgedata[addnode].path[i].vertexto].distance >
    edgedata[addnode].path[i].weight))
{
  shortpath[edgedata[addnode].path[i].vertexto].distance =
    edgedata[addnode].path[i].weight;
  shortpath[edgedata[addnode].path[i].vertexto].via = addnode;            
}

编写c++代码时,应首先使用c++编码风格。例如,你可以使用std::vector而不是数组,那么你应该使用iterator来访问向量的元素,或者使用vec.at(i),因为这两种方法可以检查超出的边界,在c中,它没有办法这样做