C ++ - 递归函数中的stringstream

时间:2012-12-18 18:31:06

标签: c++ recursion segmentation-fault stringstream

#include <sstream>
#include <string>

using namespace std;

void fRec(int i) {
    if (i == 0) {
        return;
    }

    fRec(i - 1);

    ostringstream s;
}

int main(int argc, char *argv[]) {
    fRec(50000);
    return 0;
}

运行时,会产生:

Segmentation fault (core dumped)

来自gdb的Backtrace:

#0  0x000000000040064f in fRec (i=<error reading variable: Cannot access memory at address 0x7fffc75a6f5c>) at strstr.cpp:6
#1  0x000000000040066e in fRec (i=28182) at strstr.cpp:11
#2  0x000000000040066e in fRec (i=28183) at strstr.cpp:11
#3  0x000000000040066e in fRec (i=28184) at strstr.cpp:11
#4  0x000000000040066e in fRec (i=28185) at strstr.cpp:11
#5  0x000000000040066e in fRec (i=28186) at strstr.cpp:11
...

我想问为什么会这样 - 如果我创建一个字符串对象而不是ostringstream,一切都结束了。在我看来,如果一次不能有太多的stringstream实例?

感谢您的澄清

4 个答案:

答案 0 :(得分:4)

通常自动存储(堆栈)是有界的。 50,000次递归很多。

如果您的堆栈仅为1 MB,并且整个函数调用开销中断了20个字节,那么您将会破坏堆栈。

stringstream只是一个在创建和销毁时执行操作的类,因此它将读取和写入超出堆栈顶部的内容。

要解决此问题,请不要递归50k深度。或者,增加堆栈大小(它将是编译器标志)。

答案 1 :(得分:2)

你是对的,显然50000 ostringstream个实例炸毁了堆栈。

答案 2 :(得分:2)

这是堆栈溢出。程序的堆栈大小通常是有限的。你所确定的只是std::string的大小可能比std::ostringstream小,所以它不会很快填满堆栈。这是循环结构可能优于递归的原因之一。

答案 3 :(得分:1)

您的 STACK 空间已用完。 s在堆栈上分配,您正在执行50,000次。一旦你在你的堆栈上运行OOM就会崩溃(理所当然)