如何处理或避免C ++中的堆栈溢出 [英] How to handle or avoid a stack overflow in C++

查看:235
本文介绍了如何处理或避免C ++中的堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,堆栈溢出通常导致程序无法恢复的崩溃。对于需要真正稳健的程序,这是不可接受的行为,特别是因为堆栈大小有限。有关如何处理问题的几个问题。


  1. 是否有通过一般技术防止堆栈溢出的方法。 (一个可扩展的,鲁棒的解决方案,包括处理外部库吃很多堆栈等)


  2. 有办法处理堆栈溢出他们发生?最好是堆栈解开,直到有一个处理程序来处理这个问题。


  3. 这里有语言,有可扩展堆栈的线程。


任何其他对C ++行为的解决方案有帮助的评论将不胜感激。

解决方案

处理堆栈溢出不是正确的解决方案,而是必须确保您的程序不会溢出堆栈。 / p>

不要在堆栈上分配大的变量(其中大取决于程序)。确保任何递归算法在已知的最大深度后终止。如果递归算法可能递归未知次数或大量次数,则可以自己管理递归(通过维护自己的动态分配的堆栈)或将递归算法转换为等效的迭代算法。



一个必须真正强大的程序不会使用吃了很多堆栈的第三方库或外部库。






请注意,一些平台会在发生堆栈溢出时通知程序,并允许程序处理错误。例如,在Windows上,抛出异常。这个异常不是C ++异常,但是它是一个异步异常。而C ++异常只能由一个 throw 语句抛出,异步异常可能在程序执行期间的任何时候抛出。这是预期的,但是,因为堆栈溢出可能发生在任何时间:任何函数调用或堆栈分配可能溢出堆栈。



问题是堆栈溢出(例如,从标记为 noexcept throw()的函数中抛出异常异常) code>在C ++中)。因此,即使你以某种方式处理这个异常,你也无法知道你的程序处于安全状态。因此,处理异步异常的最好方法是不处理它所有(*)。如果有人抛出,意味着程序包含一个错误。



其他平台可能有类似的方法来处理堆栈溢出错误,但是任何这样的方法都可能遇到同样的问题:预期不会导致错误的代码可能会导致错误。



(*)有一些非常罕见的异常。 / sup>


In C++ a stack overflow usually leads to an unrecoverable crash of the program. For programs that need to be really robust, this is an unacceptable behaviour, particularly because stack size is limited. A few questions about how to handle the problem.

  1. Is there a way to prevent stack overflow by a general technique. (A scalable, robust solution, that includes dealing with external libraries eating a lot of stack, etc.)

  2. Is there a way to handle stack overflows in case they occur? Preferably, the stack gets unwound until there's a handler to deal with that kinda issue.

  3. There are languages out there, that have threads with expandable stacks. Is something like that possible in C++?

Any other helpful comments on the solution of the C++ behaviour would be appreciated.

解决方案

Handling a stack overflow is not the right solution, instead, you must ensure that your program does not overflow the stack.

Do not allocate large variables on the stack (where what is "large" depends on the program). Ensure that any recursive algorithm terminates after a known maximum depth. If a recursive algorithm may recurse an unknown number of times or a large number of times, either manage the recursion yourself (by maintaining your own dynamically allocated stack) or transform the recursive algorithm into an equivalent iterative algorithm

A program that must be "really robust" will not use third-party or external libraries that "eat a lot of stack."


Note that some platforms do notify a program when a stack overflow occurs and allow the program to handle the error. On Windows, for example, an exception is thrown. This exception is not a C++ exception, though, it is an asynchronous exception. Whereas a C++ exception can only be thrown by a throw statement, an asynchronous exception may be thrown at any time during the execution of a program. This is expected, though, because a stack overflow can occur at any time: any function call or stack allocation may overflow the stack.

The problem is that a stack overflow may cause an asynchronous exception to be thrown even from code that is not expected to throw any exceptions (e.g., from functions marked noexcept or throw() in C++). So, even if you do handle this exception somehow, you have no way of knowing that your program is in a safe state. Therefore, the best way to handle an asynchronous exception is not to handle it at all(*). If one is thrown, it means the program contains a bug.

Other platforms may have similar methods for "handling" a stack overflow error, but any such methods are likely to suffer from the same problem: code that is expected not to cause an error may cause an error.

(*) There are a few very rare exceptions.

这篇关于如何处理或避免C ++中的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆