2012-01-20 24 views
1

私はこのフォーラムに新しいですし、私は私の愚かな過ちのいずれかと親切にしてくださいまだプログラミング言語で素人午前:私は検索処理のためのkdツリーを構築する再帰関数をプログラミングしていたp古典的なスタックオーバーフロー?

。私はVisual Studio '08でC言語を使用しています。

run_FAST_corner_detection.exeで0x77063de7で

未処理の例外: 0xC00000FD:今すぐコードブレークがあるとき、スタックオーバーフロー

処理のいくつかの秒後、プログラムの実行が原因、すなわちエラーを停止します

kd_node = malloc(sizeof(struct kd_node)); 
//this function allocates a pointer to a reserved memory of size struct kd_node. 

メモリ不足の古典的な問題はありますか? スタックメモリを監視するにはどうすればよいですか? (私はこの質問が繰り返し尋ねられたことを知っていますが、正直なところ私はまだこれを行うには良い方法が見つけられていません)。

+0

mallocによって割り当てられた動的メモリはスタックに割り当てられていませんヒープ上に割り当てられます。その関数呼び出しでスタックオーバーフローが発生する可能性がありますが、たぶんmallocである可能性があります。ヒープがメモリ不足にならないようにするには、mallocの結果をNULLでチェックします。 – Lundin

+0

これは古典的なスタックオーバーフローのようです。再帰関数を巻き戻したり返したりする条件は何ですか?これを繰り返しても、終了条件が正しくないとクラッシュします。機能全体を投稿することにより、より良い評価が可能になります。 –

+0

私は管理しました。 コードへのリンクは以下の通りです: https://skydrive.live.com/redir.aspx?cid=08ed71486dc5e125&resid=8ED71486DC5E125!121&parid=undefined このコードは、KDのためのKD-ツリーを作成するために使用されますツリー検索アルゴリズム。私は、再帰を避けるために尾の再帰を調べましたが、最後にifステートメントがあるため、私は実際にこの手法を使用することはできません。 私はそれを反復手順に変換することを考えていますが、樹木の作り方によってこれをどうやって行うことができるかわからないのです。 お時間をいただきありがとうございます。 – bouvett

答えて

1

まあ、スタックオーバーフローは、再帰の深いところでmallocを呼び出したことが原因である可能性があります。 mallocへの呼び出しはスタックの戻りアドレスとおそらくはパラメータをプッシュします。これはスタックがオーバーフローする原因となる可能性があります。あなたのコードで再帰をしないでください - 反復的なコードを作るようにしてください(代わりにループで)。これは、再帰が限定されていない場合に特に当てはまります。

+0

ご返信ありがとうございます。私はあなたが提案したプロセスを反復的なプロセスに変換する過程にあります。しかし、スタックメモリを監視する方法はありますか?再度ありがとう – bouvett

+1

デバッグ中または実行時に意味がありますか?デバッグ中にSPレジスタを見ることができ、スタック制限に達するまでSPレジスタがどのように減少するかを見ることができます。おそらく現在処理されていないスタックオーバーフロー例外を処理する可能性もありますが、これはデバッグの目的にのみ適している可能性があります。 – smichak

1

、スタックの使用状況を監視するだけで任意のローカル変数(関数内で定義された1)のアドレスを取得し、あなたの主な機能(またはスレッドエントリ機能)内のローカル変数のアドレスに対してそれを比較するには:

int stack_bottom; 

int stack-usage() { 
    int top = 0; 

    /* Note, stack grows downward through memory, so high - low is .. */ 
    return stack_bottom - (int)⊤ 
} 

.... 

int main() { 
    int bottom = 0; 

    stack_bottom = (int)⊥ 

    .... 
} 

スタックの使用を減らすには、再帰を制限するか、大きなローカル変数(構造体、配列など)を使用しないでください。allocaは使用しないでください。大きなローカル変数を動的に割り当てられたヒープメモリへのポインタに置き換えることができます(ただし、解放するのを忘れないでください)。

関連する問題