2012-12-18 101 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,你會崩潰(正確如此)