2012-12-18 44 views
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; 
} 

运行时,这将产生:C++ - 字符串流在递归函数

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实例?

感谢澄清

回答

2

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

2

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

4

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

如果您的堆栈仅仅是1 MB,并且整个函数调用开销打破了20个字节,那么您将会炸毁堆栈。

stringstream只是一个在创建和销毁方面做事情的类,所以它会读取和写入堆栈的顶部。

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

+0

感谢澄清家伙! – Ferrard

1

您正在用光STACK space。 s被分配到栈上,并且你正在做它50,000次。一旦你在你的堆栈上运行OOM,你会崩溃(正确如此)