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 ...
没有。甚至不能保证调用链中的每个堆栈帧大小相同。
将递归实现转换为迭代实现相当简单且定义明确:您只需
- 用显式状态容器替换隐式调用堆栈(和函数调用操作),例如
std::stack<State>
- 不是递归调用,而是将新调用的
State
压入堆栈,然后继续循环
- 循环不是被调用,而是从堆栈中弹出当前的
State
开始,然后处理它,如果您之前已经创建了另一个,则可能需要将另一个新的 State
推到那里递归调用
或者,您可以将当前的递归下降解析器拆分为分词器和 LALR(或类似)解析器,它们首先都是迭代的。例如,您可以使用 Flex 和 Bison (Lex/Yacc) 生成这些。
我正在尝试编写一个可以解析最终用户文件的库,用于将一些简单的用户生成的内容添加到项目中,我想尝试使该库尽可能灵活。我对 '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 ...
没有。甚至不能保证调用链中的每个堆栈帧大小相同。
将递归实现转换为迭代实现相当简单且定义明确:您只需
- 用显式状态容器替换隐式调用堆栈(和函数调用操作),例如
std::stack<State>
- 不是递归调用,而是将新调用的
State
压入堆栈,然后继续循环 - 循环不是被调用,而是从堆栈中弹出当前的
State
开始,然后处理它,如果您之前已经创建了另一个,则可能需要将另一个新的State
推到那里递归调用
或者,您可以将当前的递归下降解析器拆分为分词器和 LALR(或类似)解析器,它们首先都是迭代的。例如,您可以使用 Flex 和 Bison (Lex/Yacc) 生成这些。