2010-11-23 147 views
1

我正在編寫一個程序,作爲學校的一項任務,儘管我已經計算出所有的錯誤,直到我決定調用我的拷貝構造函數。該程序是交互式(CLI),基本上有兩種模塊:LList類的.h和.cpp文件,程序結構的.h和.cpp文件以及main()的第三個cpp文件。假設它是一個水電工程公司(假公司)的程序,其中LLIST節點保存每年在河流中的水流量(年和流量)的數據。這裏是關於類的一些見解:C++鏈接列表分段錯誤

//list.h 
struct ListItem { 
    int year; 
    double flow; 
}; 

struct Node { 
    ListItem item; 
    Node *next; 
}; 

class FlowList { 
public: 
    FlowList(); 
    // PROMISES: Creates empty list 

    FlowList(const FlowList& source); 
    // REQUIRES: source refers to an existing List object 
    // PROMISES: create the copy of source 

    ~FlowList(); 
    // PROMISES: Destroys an existing list. 

    FlowList& operator =(const FlowList& rhs); 
    // REQUIRES: rhs refers to an existing FlowList object 
    // PROMISES: the left hand side object becomes the copy of rhs 

    //....Other member functions 

private: 
    // always points to the first node in the list. 

    Node *headM; 
    // Initially is set to NULL, but it may point to any node. 

    Node *cursorM; 
    //For node manipulation within interactive CLI 

    void copy(const FlowList& source); 

    void destroy(); 

我相信內存泄漏或碰撞的複製功能,但不能銷點內正在某處。如果我創建一個FlowList對象,從.dat文件數據填充它

//list.cpp 

FlowList::FlowList() : headM(0), cursorM(0) {} 

FlowList::FlowList(const FlowList& source) 
{ 
    copy(source); 
} 

FlowList::~FlowList() 
{ 
    destroy(); 
} 

FlowList& FlowList::operator =(const FlowList& rhs) 
{ 
    if (this != &rhs) 
    { 
    destroy(); 
    copy(rhs); 
    } 
    return (*this); 
} 

//...more function definitions 

void FlowList::copy(const FlowList& source) 
{ 
    if (source.headM == NULL) 
    { 
    headM = NULL; 
    cursorM = NULL; 
    return; 
    } 

    Node* new_node = new Node; 
    assert(new_node); 
    new_node->item.year = source.headM->item.year; 
    new_node->item.flow = source.headM->item.flow; 
    new_node->next = NULL;  
    headM = new_node; 

    Node* thisptr = new_node; 

    for(Node* srcptr = source.headM->next; srcptr != NULL; srcptr = srcptr->next) 
    { 
    new_node = new Node; 
    assert(new_node); 
    new_node->item.year = srcptr->item.year; 
    new_node->item.flow = srcptr->item.flow; 
    new_node->next = NULL; 
    thisptr->next = new_node; 
    thisptr = thisptr->next; 
    } 

} 

void FlowList::destroy() 
{ 
    Node* ptr = headM; 
    Node* post = headM->next; 

    while (ptr != NULL) 
    { 
    delete ptr; 
    ptr = post; 
    if (post) 
     post = ptr->next; 
    } 
    headM = NULL; 
} 

該項目工程的罰款;然後,我可以操作程序中的數據(顯示,執行計算,添加到列表中,從列表中刪除並將數據保存到文件中),但是如果創建另一個FlowList對象(在main.cpp中),程序崩潰(分段故障)。 任何幫助將非常感激。

+0

爲什麼你有複製構造函數和析構函數調用其他函數而不是在那裏做工作? – Falmarri 2010-11-23 00:09:50

+1

副本中,你沒有設置cursorM if(source.headM!= NULL)(只是讓我覺得奇怪的東西) – Akusete 2010-11-23 00:11:29

回答

4

我發現最初的事情是,它看起來像你的destroy()函數總是分割的錯,如果列表爲空:

void FlowList::destroy() 
{ 
    Node* ptr = headM; 
    Node* post = headM->next; 
    //... 
} 

如果該列表是空的,headMNULL,然後你想做headM->next在那種情況下將總是產生分段錯誤。

我想如果你傳遞一個空的列表,你可能在你的拷貝構造函數中有內存泄漏。如果你看一下這個代碼:

void FlowList::copy(const FlowList& source) 
{ 
    if (source.headM == NULL) 
    { 
    headM = NULL; 
    cursorM = NULL; 
    return; 
    } 
    //... 
} 

如果當前有哪些列表包含20項和source是一個空列表?您將當前列表的headMcursorM設置爲NULL,但您從不在最初使用new創建的當前列表中的任何節點上調用delete。你可能想把你的destroy()函數也放到你的拷貝構造函數中(你爲operator=函數做過)。

我注意到的最後一件事是,您不會在copy()函數中初始化cursorM以獲得非空列表(@Akusete也指出了這一點)。我想我會建議你在複製構造函數的開頭,只是初始化cursorMheadMNULL只是爲了覆蓋你的基地。

看起來你真的很接近,我認爲你真的需要考慮處理空列表的邊界情況(在LHS和RHS上),你可能會發現大部分這些錯誤。祝你好運!