2012-02-28 12 views
2
#include<iostream> 
using namespace std; 

class A 
{ 
public: 

virtual void f() = 0; 
}; 

class B: public A 
{ 
public: 

void f() 
{ 
// f(); //segmentation Fault 
cout<<"\bB's f() called"<<endl; 
f(); //recursive loop 
} 
}; 

void A:: f() 
{ 
cout<<"\nA's f() called"<<endl; 
} 

    int main() 
    { 

    A *ptr; 
    B b; 

    ptr = &b; 
    b.f(); 

    return 0; 
    } 

Q-が来ているのはなぜ> .. BクラスFの内側()、我々は、F(呼び出す場合)には、セグメンテーションフォールトを与えるとcoutの<」後「はcout < <」文の前に< "ステートメントは再帰的ループを与えます。なぜセグメンテーション障害が起こっているのか。事前に感謝:)セグメンテーションフォールトが

+0

あなたは何が起こると思いますか? – Mat

+0

私の推測では、なぜスタックオーバーフローを起こすのかという問題ではないということです。なぜなら、再帰呼び出しの場所によって結果が異なるのはなぜだろうか。 – Till

答えて

2

は最初cout<<が起こる前回の再帰的に無限の量と呼ばれるようにcout<<原因f()f()を配置します。両方の問題は概念的に同じですが、異なる出力を提供します。

+1

違いの理由は、2番目のケースでのコンパイラの最適化です。通常、どちらも遅かれ早かれスタックオーバーフローのためセグメンテーションが発生します。 –

5

関数の最後で再帰呼び出しを行うと、コンパイラはスタックの使用を最適化し、恐らくそれを削除します。参照:http://en.wikipedia.org/wiki/Tail_call。セグメンテーションフォルトの理由は、スタックオーバーフローです!

0

再帰ループは、です。問題の原因です。それは決してand、そしてコールスタックがいっぱいになるでしょう。

停止条件がありません。

0

無限ループのためにスタックオーバーフローが発生しています。最終的にはfout()を呼び出して最終的に1つを得るでしょう< < ...しかし、それ以前にはもっと早くそこに着きます。コンパイラがこれにも影響するいくつかの最適化を行うのであれば、私は驚くことはありません。

再帰的ループを途切れさせる方法を追加する必要があります。

関連する問題