2014-05-19 136 views
1

我想創建一個樹結構使用一些讀取流時調用的處理函數。我認爲問題在於,我的變量是在函數的作用域中創建的,並且在函數結束時會消失,並且指針指向無。C++指針和變量範圍

我不知道採取什麼方法來保持內存中的對象,同時仍然允許樹是可擴展的。

我已經做了一個簡化版本的代碼:它編譯和運行,但'段'對象的父子關係都是錯誤的。

class Segment 
{ 
public: 
    Segment* parent; 
    list<Segment*> children; 
    string name; 
}; 

void OpenSegment(Segment* p_segCurrentseg); 
void CloseSegment(Segment* p_segCurrentseg); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Segment parent; 
    parent.name="parent"; 
    Segment* p_segCurrentseg=&parent; 
    OpenSegment(p_segCurrentseg); 
    OpenSegment(p_segCurrentseg); 
    OpenSegment(p_segCurrentseg); 
    CloseSegment(p_segCurrentseg); 
    return 0; 
} 

void OpenSegment(Segment* p_segCurrentseg) 
{ 
    Segment child; 
    child.name="child"; 
    p_segCurrentseg->children.push_front(&child); 
    child.parent=p_segCurrentseg; 
    p_segCurrentseg=&child; 
} 

void CloseSegment(Segment* p_segCurrentseg) 
{ 
    p_segCurrentseg=p_segCurrentseg->parent; 
} 
+0

也許它爲你編譯,但它肯定不會編譯我。無論如何,看起來你需要使用'new'。 – ooga

回答

2

你的代碼有幾個問題。

  1. 您按值傳遞p_segCurrentseg並分配給另一個指針。這對調用函數中的變量沒有影響。

  2. 正如您已經懷疑的那樣,您正嘗試將p_segCurrentseg指定爲當您從該函數返回時將會消失的變量。

你可以做什麼:

  1. p_segCurrentseg參考指針。

  2. 從堆中創建一個對象並指定p_segCurrentseg指向它。

這裏是我的OpenSegment建議:

void OpenSegment(Segment*& p_segCurrentseg) 
{ 
    Segment* child = new Segment; 
    child->name="child"; 
    p_segCurrentseg->children.push_front(child); 
    child->parent=p_segCurrentseg; 
    p_segCurrentseg=child; 
} 
+0

非常感謝!你是傳奇 – user3651203

+0

@ user3651203很高興我可以幫助:) –

0

的問題是在OpenSegment()方法,尤其是在這3行:

Segment child; 
child.name="child"; 
p_segCurrentseg->children.push_front(&child); 

首先,孩子是一個局部變量並在堆棧上創建。然後,您將孩子的地址推入列表中。當OpenSegment()返回時,由於本地變量的存儲被釋放,所以子地址包含垃圾。

解決方案是將child定義爲指向Segment的指針,在堆上創建它,以便它在OpenSegment()返回後仍然存在。你必須確保釋放它的記憶。適當的地方是爲你的Segment類定義一個析構函數。在它中,迭代(子節段)列表併爲每個子節點釋放內存。

+0

謝謝你,以及 – user3651203