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回の再帰はたくさんあります。

スタックがわずか1MBで、関数呼び出しのオーバーヘッド全体が20バイトを超える場合、スタックを爆破します。

stringstreamは、作成と破棄を行うクラスであるため、スタックの最上位を超えて読み取りと書き込みを行います。

これを修正するには、50kの深さで再帰しないでください。または、スタックサイズを増やします(コンパイラフラグになります)。

于 2012-12-18T18:34:52.900 に答える
2

あなたは正しいです、どうやら50000ostringstreamインスタンスがスタックを爆破します。

于 2012-12-18T18:34:11.143 に答える
2

これはスタックオーバーフローです。プログラムのスタックサイズは通常制限されています。あなたが決定したのは、std::stringおそらくそれよりもサイズが小さいstd::ostringstreamので、スタックがすぐにいっぱいになることはないということです。これが、ループ構造が再帰よりも優先される理由の1つです。

于 2012-12-18T18:34:59.083 に答える
1

スタックスペースが不足しています。sはスタックに割り当てられ、50,000回実行しています。スタックでOOMを実行すると、クラッシュします(当然のことながら)

于 2012-12-18T18:35:12.530 に答える