【问题标题】:avoid stack over flow c++避免堆栈溢出 C++
【发布时间】:2020-03-08 21:22:39
【问题描述】:

它是由另一个系统生成的程序,因此它可能是重复的,效率或智能较低。结果发现它有很大的依赖关系,陷入了深度递归函数。

因为向量可以包含 1000 个元素并且它必须是连续的。崩溃时的调用堆栈“Calculation::getItem(9)”>“Calculation::getItem(8)”>“Calculation::getItem(7)”>“Calculation::getItem(6)”...它之前崩溃了返回 100 的正确结果。

新问题是:在不增加堆栈大小或更改递归函数设计的情况下解决堆栈溢出的任何方法。

计算.cpp

std::optional<std::any> Calculation::getItem(int rowNo)
{
    if(calculatedRow[rowNo].has_value())
    {
      return calculatedRow[rowNo];
    }
    switch(rowNo)
    {
        case 0 : return calculatedRow[rowNo] = 0;
        case 1 : return calculatedRow[rowNo] = 100;
        case 2 : return calculatedRow[rowNo] = getItem(1)
        case 3 : return calculatedRow[rowNo] = getItem(2)
        case 4 : return calculatedRow[rowNo] = getItem(3)
        case 5 : return calculatedRow[rowNo] = getItem(4);
        case 6 : return calculatedRow[rowNo] = getItem(5)
        case 7 : return calculatedRow[rowNo] = getItem(6);
        case 8 : return calculatedRow[rowNo] = getItem(7);
        case 9 : return calculatedRow[rowNo] = getItem(8);
...
    }
    return 0;
}

计算.h

namespace Calculation
{
    //private namespace
    namespace
    {
       std::vector<std::optional<std::any>> calculatedRow(1000);
    }

    std::optional<std::any> getItem(int rowNo);
};

【问题讨论】:

  • 不一定是向量。递归不是免费的,它需要调用堆栈空间。如果您有一个特别深的调用堆栈,那么该空间可能会被进一步的递归耗尽。
  • 感谢您的回复,从没想过递归可能是一种昂贵的方法。
  • 当你的 C++ Segfaults 从不内存问题,它总是自己的错。
  • @nada 痴迷于递归教学的 CS 101 处理器的秘密社团肯定有一些错误。
  • @parktomatomi 特别是递归,就像“计算整数”一样令人震惊

标签: c++ recursion segmentation-fault c++17 stack-overflow


【解决方案1】:

我稍微修改了您的代码并运行它。当我用一个非常大的数字1024 * 128 - 1 运行它时,我得到了一个错误。所以,我认为你的错误与调用堆栈限制有关。我的推论是由于您使用了递归,超出了调用堆栈限制和程序崩溃。我想在下面分享useful question 和我的代码。

Calculation.h

#include <optional>
#include <any>
#include <vector>

namespace Calculation {
    //private namespace
    namespace {
        std::vector<std::optional<std::any>> calculatedRow(1024 * 128);
    }

    std::optional<std::any> getItem(int rowNo);
};

Calculation.cpp

#include <optional>
#include <any>
#include <iostream>
#include "Calculation.h"


std::optional<std::any> Calculation::getItem(int rowNo) {
    std::cout << rowNo << std::endl;
    if (calculatedRow[rowNo].has_value()) {
        return calculatedRow[rowNo];
    }
    switch (rowNo) {
        case 0 :
            return calculatedRow[rowNo] = 0;
        case 1 :
            return calculatedRow[rowNo] = 100;
    }
    return calculatedRow[rowNo] = getItem(rowNo - 1);
}

ma​​in.cpp

#include "Calculation.cpp"

int main() {
//    auto retVal = Calculation::getItem(1);
    auto retVal = Calculation::getItem(1024 * 128 - 1);
    if (retVal.has_value()) {
        std::printf("%d\n", std::any_cast<int>(retVal.value()));
    }
    return 0;
}

当我通过CLion 运行它时,获得的日志是:

...
43776
43775
43774
43773
43772
43771
43770
43769

Process finished with exit code 11

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 2013-10-29
    • 2010-12-04
    • 2016-07-12
    • 2011-09-21
    • 2015-11-14
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多