【问题标题】:How to handle segmentation fault in an array C++如何处理数组 C++ 中的分段错误
【发布时间】:2013-12-16 05:13:13
【问题描述】:

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

//--------------------------------------------------------------------------
// '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 - 你没有在你显示的代码中执行任何操作。
  • 这是当我设置我试图不允许它为 NULL 时从 Dev C++ 抛出的错误代码(也许它考虑比较算术?)。如何避免访问越界索引?有时有值,但有时没有。
  • 我想出了如何让它停止!我跟踪每个顶点连接到的顶点数 (edgecount),所以我只是更改了 i
  • 如果您使用 C++ 进行开发,为什么不使用一个合理的、用户友好的容器,例如向量或列表?正如您所注意到的,数组很难正确使用。

标签: c++ arrays graph


【解决方案1】:

如果您的逻辑经常遇到 NULL 对象,那么您的代码中可能存在较大的设计或实现问题,但要解决您当前的问题,最简单的方法是使用 std::array&lt;&gt;::at(),而不是 std::array&lt;&gt;::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;            
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 提出更好的替代方案固然很好,但这无助于 OP 学习如何解决手头的问题。
    猜你喜欢
    • 2014-04-10
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2017-04-11
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多