【发布时间】:2014-08-14 05:53:28
【问题描述】:
在c++中递归什么时候会导致stackoverflow错误?使用递归时消耗的内存大小是多少?它是调用函数的 4 倍(4 是指针的大小)吗?这是否意味着每个调用都有一个不同的指针?
【问题讨论】:
-
您可能想了解一下堆栈,here 是一个不错的开始。
在c++中递归什么时候会导致stackoverflow错误?使用递归时消耗的内存大小是多少?它是调用函数的 4 倍(4 是指针的大小)吗?这是否意味着每个调用都有一个不同的指针?
【问题讨论】:
每个平台都对您可以在程序中使用的堆栈帧的数量有所限制。当递归函数没有足够快地满足其终止条件时,就会导致堆栈溢出。
在 Microsoft Visual Studio 编译器中,您可以使用编译器选项 /F 指定堆栈大小(还有一个链接器选项 /STACK)。没有这个,堆栈大小为 1 MB。您可以通过http://msdn.microsoft.com/en-us/library/tdkhxaks.aspx获取更多信息。
每个栈帧需要不同的内存量——它们由局部变量的数量和类型、返回值的类型、参数的数量和类型决定。因此,您可以使用的堆栈帧数不会导致堆栈溢出。
g++/gcc 还有一种使用-Wl-stack_size 指定堆栈大小的方法。你可以在Change stack size for a C++ application in Linux during compilation with GNU compiler找到更多关于该主题的信息。
【讨论】:
C++ 作为一种语言没有“堆栈”或“堆栈溢出”的概念。
堆栈是一个实现细节。每次调用消耗的数量取决于您的平台、编译器、实际代码等。根据经验,您可以期望返回地址和函数的所有参数都被压入堆栈。此外,自动变量通常存在于堆栈中(但见下文)。
不过,这是一种简化:在某些情况下,编译器可能能够完全消除函数调用或turn them into jump instructions。参数通常在寄存器中传递。自动变量可以被优化掉或存储在寄存器中。等等等等。
如果您想确定,请将您的代码编译为汇编并仔细研究结果。或者,设置一些具有代表性的基准并运行它们,直到堆栈耗尽。
最后但同样重要的是,应用程序可用的堆栈数量通常可以在操作系统级别进行配置。
【讨论】: