【问题标题】:How to fix a stack overflow error caused by recursive functions? C++如何修复递归函数导致的堆栈溢出错误? C++
【发布时间】:2020-09-11 18:31:58
【问题描述】:

如标题所示,我认为递归函数导致我的程序堆栈溢出。而且需要递归逻辑,如何解决?

代码:

static bool orient_flip_face(HE *edge)
{
    if(edge->flip == NULL)
        return 1;
    return orient_face(face);
}

static bool orient_face(HEF *face)
{
    assert(face->oriented);
    return orient_flip_face(face->edge);
}

static bool build_HE(he::Mesh_Data *mesh,
                     std::vector<HEV*> *hevs,
                     std::vector<HEF*> *hefs)
{
     // process mesh data
     // ...

     return orient_face(first_face);
}

基本上 orient_faceorient_flip_face 来回调用对方,直到它是最后一个顶点。当我通过一个简单的网格时很好,但是当我通过具有 63690 个顶点的 stanford rabbit 时,它会溢出。然后我将 stack reversed size 增加到 40MB 并修复了堆栈溢出错误。但这是一个合理的解决方案吗?

谢谢!

【问题讨论】:

  • 请出示代码。没有代码我们只能猜测,这可能对你没有帮助。
  • 对不起!现在添加它
  • 您可以尝试将其转换为循环。
  • 重要的区别是无限递归和大但仍然有限的递归。无限回溯实际上是一个逻辑错误。但是,如果递归是有限的,则可以对其进行优化。
  • 至于问题的可能原因,你记得初始化你的结构吗?此外,您在“列表”中将多少个对象链接在一起?最后,您显示的代码不是正确的minimal reproducible example,尤其是考虑到它包含不相关的错误(在orient_flip_face 函数中,face 是什么?)

标签: c++ recursion graphics stack-overflow


【解决方案1】:

您可能会遇到巨大的递归甚至无限递归循环。尝试检查您的基本情况条件并验证递归是否在有限限制内停止。

【讨论】:

  • 谢谢!基本案例有效!当有 63690 个呼叫时它崩溃了。
  • 您能否在问题中添加更多详细信息。不知道更多细节很难提供帮助。
  • 当然!刚刚添加!
【解决方案2】:

您的代码是 尾递归 的示例,因为递归调用是每个函数中执行的最后一件事。尾递归很容易转化为非递归循环。以下代码与您拥有的代码等效,根本不使用递归。

static bool orient_face(HEF *face)
{
    for (;;)
    {
        assert(face->oriented);
        HE *edge = face->edge;
        if (edge->flip == NULL)
            return 1;
    }
}

static bool build_HE(he::Mesh_Data *mesh,
                     std::vector<HEV*> *hevs,
                     std::vector<HEF*> *hefs)
{
     // process mesh data
     // ...

     return orient_face(first_face);
}

正如一些程序员老兄指出的那样,代码实际上是一个空操作(除了断言,但我假设这只是一个调试细节,而不是代码的重点)。因此,除非发生其他事情,否则您可以将其完全删除。

细节很重要。

【讨论】:

  • 哇,我通过使用 while 循环替换递归来解决您的建议!谢谢约翰!!
猜你喜欢
  • 2011-02-26
  • 2020-08-03
  • 2013-04-05
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
相关资源
最近更新 更多