C++ C++;运行时抢占堆栈溢出

C++ C++;运行时抢占堆栈溢出,c++,recursion,memory,stack-overflow,C++,Recursion,Memory,Stack Overflow,我正在尝试编写一个库,它可以解析最终用户文件,用于将一些简单的用户生成的内容添加到项目中,我希望尝试使库尽可能灵活。我将递归用于“对象”的标记化过程,该过程通过一个由四个函数组成的链,但我对如何处理最终用户使用嵌套对象的潜在情况感到矛盾。我知道我可以对程序可以递归的次数设置一个硬限制,但我希望它尽可能灵活。是否有任何方法可以计算此进程可以执行的(最大-1)次数,以便抢占堆栈溢出错误并返回错误或要处理的内容?在Windows上,您可以使用SEH框架使用u try/u except捕获堆栈溢出异常,

我正在尝试编写一个库,它可以解析最终用户文件,用于将一些简单的用户生成的内容添加到项目中,我希望尝试使库尽可能灵活。我将递归用于“对象”的标记化过程,该过程通过一个由四个函数组成的链,但我对如何处理最终用户使用嵌套对象的潜在情况感到矛盾。我知道我可以对程序可以递归的次数设置一个硬限制,但我希望它尽可能灵活。是否有任何方法可以计算此进程可以执行的(最大-1)次数,以便抢占堆栈溢出错误并返回错误或要处理的内容?

在Windows上,您可以使用SEH框架使用u try/u except捕获堆栈溢出异常,然后退出程序。
但是,如果应用程序使用C++,则需要使用/EHA或EHSC标志编译。 有关将SEH与C\C++一起使用以及使用/EHa和/EHsc标志的详细信息,请查看此链接。


希望这有帮助

在Windows上,您可以使用SEH框架捕获堆栈溢出异常,方法是使用\uu try/\uu except并退出程序。
但是,如果应用程序使用C++,则需要使用/EHA或EHSC标志编译。 有关将SEH与C\C++一起使用以及使用/EHa和/EHsc标志的详细信息,请查看此链接。

希望这有帮助

是否有任何方法可以计算这个[递归]过程可以执行的(最大-1)次数

不,甚至不能保证调用链中的每个堆栈帧大小相同

将递归实现转换为迭代实现非常简单,而且定义非常明确:您只需

  • 将隐式调用堆栈(和函数调用操作)替换为显式状态容器,例如
    std::stack
  • 不是递归调用,而是将新调用的
    状态
    推到堆栈上,然后继续循环
  • 循环不是被调用,而是首先从堆栈中弹出当前的
    状态
    ,然后处理这些状态,如果您以前进行过另一次递归调用,则可能需要在那里推另一个新的
    状态
  • 或者,您可以将当前的递归下降解析器拆分为标记器和LALR(或类似)解析器,这两个解析器首先都是迭代的。例如,您可以使用Flex和Bison(Lex/Yacc)生成它们

    是否有任何方法可以计算这个[递归]过程可以执行的(最大-1)次数

    不,甚至不能保证调用链中的每个堆栈帧大小相同

    将递归实现转换为迭代实现非常简单,而且定义非常明确:您只需

  • 将隐式调用堆栈(和函数调用操作)替换为显式状态容器,例如
    std::stack
  • 不是递归调用,而是将新调用的
    状态
    推到堆栈上,然后继续循环
  • 循环不是被调用,而是首先从堆栈中弹出当前的
    状态
    ,然后处理这些状态,如果您以前进行过另一次递归调用,则可能需要在那里推另一个新的
    状态

  • 或者,您可以将当前的递归下降解析器拆分为标记器和LALR(或类似)解析器,这两个解析器首先都是迭代的。例如,您可以使用Flex和Bison(Lex/Yacc)生成它们。

    任何递归都可以重写为迭代加显式堆栈。这样,您就不受调用堆栈大小的限制,而只受系统上可用内存的限制。C++标准没有指定用于确定递归函数调用所需的可用堆栈空间的方法,也没有指定进程可用的堆栈空间。@ IgorTandetnik听起来很有趣,是一个不错的方法。链中的函数执行许多检查,一些检查和返回信息备份到链中。你能给我指一下关于可能实现的任何教程或文章吗?任何递归都可以重写为迭代加显式堆栈。这样,您就不受调用堆栈大小的限制,而只受系统上可用内存的限制。C++标准没有指定用于确定递归函数调用所需的可用堆栈空间的方法,也没有指定进程可用的堆栈空间。@ IgorTandetnik听起来很有趣,是一个不错的方法。链中的函数执行许多检查,一些检查和返回信息备份到链中。您能给我指出任何关于可能实现的教程或文章吗?
    __try  
    {  
        //code which might generate stack overflow  
    }  
    __except(EXCEPTION_EXECUTE_HANDLER)  
    {  
        //handle stack overflow exception, throw error and exit program     
    }