C++ 运行 次抢占堆栈溢出

C++ Run-time Preempting Stack-Overflows

我正在尝试编写一个可以解析最终用户文件的库,用于将一些简单的用户生成的内容添加到项目中,我想尝试使该库尽可能灵活。我对 'objects' 的标记化过程使用递归,它通过四个函数链,但我对如何处理最终用户对嵌套对象感到满意的潜在情况感到矛盾。我知道我可以对程序可以递归的次数设置一个硬性限制,但我想让它尽可能灵活。有什么方法可以计算出这个进程可以执行的(最大 - 1)次,以便我可以抢占堆栈溢出错误和 return 一个错误或要处理的东西?

在 Windows 上,您可以使用 SEH 框架使用 __try/__except 捕获堆栈溢出异常并退出您的程序。
但是,如果您的应用程序使用 C++,则需要使用 /EHa 或 /EHsc 标志进行编译。 查看此 link 以了解有关将 SEH 与 C\C++ 一起使用的更多详细信息以及使用 /EHa 和 /EHsc 标志的细节。
https://docs.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp

__try  
{  
    //code which might generate stack overflow  
}  
__except(EXCEPTION_EXECUTE_HANDLER)  
{  
    //handle stack overflow exception, throw error and exit program     
} 

希望对您有所帮助!

Is there any way that I can calculate the (maximum - 1) number of times that this [recursive] process can execute ...

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

将递归实现转换为迭代实现相当简单且定义明确:您只需

  1. 用显式状态容器替换隐式调用堆栈(和函数调用操作),例如std::stack<State>
  2. 不是递归调用,而是将新调用的 State 压入堆栈,然后继续循环
  3. 循环不是被调用,而是从堆栈中弹出当前的 State 开始,然后处理它,如果您之前已经创建了另一个,则可能需要将另一个新的 State 推到那里递归调用

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