2011-07-17 29 views
2

我正在處理這段代碼,並且一直在收到分段錯誤。對於我的生活,我不知道爲什麼,我知道一個分段錯誤是當你試圖遵循一個空指針時,但事實是,在我的代碼中,「u-> previous」isnt null,既不是「u」,I檢查。如果我將while循環中的條件更改爲(u!= NULL),它會在「u-> isGreen」發生故障前迭代兩次,再一次檢查每個迭代以查看u是否爲空。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; 
} 

「節點」是指向實際節點對象的指針數組。我確定我的節點中存在「u-> previous」,並且「isGreen」被初始化爲false;

繼承人的Node類,如果你想看到的是:

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[]); 
}; 

什麼引起的賽格故障?

+1

你也應該包含'Node'類的實現。 –

+0

'extractOptimalPath()'和'extractOptimalPath(Node * graph []);'是什麼關係? – cnicutar

+0

你使用過調試器嗎?它可能有助於瞭解「u」究竟指的是什麼(它不足以知道它不是'0')。 –

回答

7

該錯誤不是只是爲空指針,它是一個指向任何無效的指針。這可以是null,但它也可以是釋放的內存。

+0

其他原因可能包括受惡意寫入或使用未正確初始化的節點損壞的節點。 –

+0

我認爲你是正確的,它是被釋放的內存(調試它)需要做些什麼來阻止它被釋放? – Matt

+0

@Matt:沒有釋放它。使用智能指針和RAII,遵循三法則(所有這些在SO和維基百科以及其他地方都有詳細記錄) – jalf

4

我看不到Node中的拷貝構造函數,而我看到指針和析構函數。所以你違反了Rule of Three。因此,如果您不小心複製了一個節點,那麼該副本的析構函數將導致您現在看到的效果。

更新: 若要快速測試這一點,添加一個私有的拷貝構造函數到您的節點類,如下:

class Node { 
... 

private: 
    Node(const Node&); 
}; 

如果你現在得到編譯器錯誤,您正在拷貝。編譯器會指出你發生的位置。

0

你不需要有一個NULL指針有一個分段錯誤,它發生每次你訪問內存超出你的允許範圍。檢查線程What is a segmentation fault?

您的代碼不足以說明導致段錯誤的原因。在你的一個節點中,最有可能的是u->previous指向一些或多或少隨機的內存,但這只是一個猜測。

0

我的猜測是,在您的Node對象的構造函數中,以前的指針在任何時候都不會設置爲NULL。當previous設置爲NULL時,你應該有一點(在你的實際代碼中,不要假設代碼會自動爲你做這件事)。另外,作爲提示,請嘗試使用gdb to step through your code。另一個提示valgrind通常用於諮詢內存泄漏,但我也用它來成功查明段錯誤。