0
#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 的回溯:

#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

4 回答 4

4

很多时候自动存储(堆栈)是有界的。50,000 次递归已经很多了。

如果您的堆栈只有 1 MB,并且整个函数调用开销超过 20 个字节,那么您的堆栈就会崩溃。

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

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

于 2012-12-18T18:34:52.900 回答
2

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

于 2012-12-18T18:34:11.143 回答
2

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

于 2012-12-18T18:34:59.083 回答
1

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

于 2012-12-18T18:35:12.530 回答