2011-07-17 15 views
2

私はこのコードを作業していますが、セグメンテーションエラーが発生しています。私の人生のために、私はなぜ、私はあなたがnullポインタをたどろうとするとセグメント違反があることを知ることはできませんが、事は、私のコードでは "u->前の" isntヌル、どちらも "u"チェックwhileループの条件を(u!= NULL)に変更すると、「u-> isGreen」にフォールトする前に2回反復されます。もう一度、すべての繰り返しをチェックして、uがnullかどうかを確認します。C++は分かりにくいセグメンテーションエラー

int extractOptimalPath() { 
    Node *u = nodes[NUM_NODES - 1]; 

    int i = 0; 
    while (u != NULL) { 
     cout << i << endl; 
     u->isGreen = true; 
     u = u->previous; 
     i++; 
    } 
    return 0; 
} 

"nodes"は、実際のNodeオブジェクトへのポインタの配列です。私は自分のノードに "u-> previous"が存在し、 "isGreen"がfalseに初期化されていることを確認しています。ワンセグ障害を引き起こしている可能性が何

class Node { 
    public: 
     GLfloat x, y, z; 
     int numLinks; 
     Node *link1; 
     Node *link2; 
     GLfloat distance; 
     Node *previous; 
     bool isGreen; 

     Node(GLfloat x, GLfloat y, Node *link1, Node *link2); 
     Node(GLfloat x, GLfloat y, Node *link1); 
     Node(); 
     Node(GLfloat x, GLfloat y); 
     ~Node(); 

     bool dijkstra(Node* graph[], Node *source, Node *target); //returns true if a path to target is found 
     int dist(Node *n1, Node *n2); 
     int extractOptimalPath(Node* graph[]); 
}; 

相続人Nodeクラスは、ケースであなたはそれを見たいですか?

+1

あなたは 'Node'クラスの実装も含めるべきです。 –

+0

'extractOptimalPath()'と 'extractOptimalPath(Node * graph []);の関係は何ですか? – cnicutar

+0

デバッガを使用しましたか?正確に 'u'が何を指しているのか知るのに役立ちます(' 0'でないことを知るのに十分ではありません)。 –

答えて

7

このエラーはnullポインタの場合はであり、無効なものを指すポインタです。 nullでもかまいませんが、解放されたメモリーでもかまいません。

+0

追加の理由には、不正な書き込みによって破損したノードや、適切に初期化されていないノードを使用することがあります。 –

+0

あなたはそれが解放された記憶であるとあなたは正しいと思います。(デバッグしました)解放されるのを止めるには何が必要ですか? – Matt

+0

@Matt:それを解放しないでください。スマートポインタとRAIIを使用し、3つのルールに従ってください(これらはすべて、SOとWikipediaなどで十分に文書化されています) – jalf

4

ノードにコピーコンストラクタは表示されませんが、ポインタとデストラクタが表示されます。あなたはRule of Threeに違反しました。

その結果、誤ってノードをコピーした場合、そのコピーのデストラクタによって、現在表示されているエフェクトが発生します。

更新: すぐにこのをテストするために、このように、あなたのNodeクラスにプライベートコピーコンストラクタを追加します。あなたは今、コンパイルエラーが出る場合

class Node { 
... 

private: 
    Node(const Node&); 
}; 

、あなたはコピーを作っています。コンパイラは、それが起こる場所を指し示します。

0

セグメンテーションフォルトを持つためにNULLポインタを持つ必要はありません。これは、許可されたスコープからメモリにアクセスするたびに発生します。スレッドWhat is a segmentation fault?を確認してください。

あなたのコードは、セグメンテーションフォルトの原因を言うのに十分ではありません。おそらく、あなたのノードの1つにあるu->previousは、多かれ少なかれランダムなメモリを指していますが、それは単なる推測です。

0

私の推測では、Nodeオブジェクトのコンストラクタでは、前のポインタは決してNULLに設定されません。前の値がNULLに設定されている必要があります(実際のコードでは、コードが自動的にこれを行うとは仮定しないでください)。また、ヒントとして、gdb to step through your codeを試してみてください。もう1つのヒント、valgrindは通常、メモリリークを調べるために使用されますが、segfaultも正確に特定するために使用しています。

関連する問題