2011-12-27 92 views
1

我只是創建一個簡單的列表,然後摧毀它。而事情錯了,我總是得到這個惱人的錯誤消息:C++新手:析構函數

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 

下面的代碼:

#include<iostream> 
#include<Windows.h> 
using namespace std; 

struct node 
{ 
    int data; 
    node *next; 
}; 

class list 
{ 
protected: 
    node *top; 
public: 
    list() 
    { 
     top=NULL; 
    } 

    list random() 
    { 
     int x=rand()%10; 
     for(int i=0; i<x; i++) 
     { 
      node *p=new node; 
      p->data=rand()%100; 
      p->next=top; 
      top=p; 
     } 
     return *this; 
    } 

    void show() 
    { 
     for(node *p=top; p; p=p->next) 
     { 
      cout<<p->data<<" "; 
     } 
     cout<<"\n"; 
    } 

    ~list() 
    { 
     node *r; 
     for(node *p=top; p; p=r) 
     { 
      r=p->next; 
      delete p; 
     } 
    } 
}; 

int main() 
{ 
    srand(GetTickCount()); 
    list a; 
    a.random().show(); 
    return 0; 
} 
+6

您違反了[三條規則](http://stackoverflow.com/q/4172722/636019)。 – ildjarn 2011-12-27 23:41:36

回答

0

你的問題是,你要複製你的list,但你沒有定義拷貝構造函數。隱式定義的複製構造函數只會複製top指針,因此最終嘗試刪除相同的兩個節點鏈。

當您從random()成員函數按值返回*this的副本時,複製發生。

最短的修復方法是通過在類的專用部分中聲明覆制構造函數和複製賦值運算符來使您的類不可複製。

private: 
    list(const list&); 
    list& operator=(const list&); 

然後,您可以讓random回報void,似乎沒有成爲一個很好的理由,爲什麼它使一個副本,以及。

然後,您可以叫它像這樣:

list a; 
    a.random(); 
    a.show(); 

較長的解決將是讓你list可複製通過使全面實施list(const list&)list& operator=(const list&)是正確複製源list是所有節點複製。

+0

謝謝,這麼好解釋 – 2011-12-29 10:53:50

3

此:

list random() 

應該是:

list &random() 

的原因是,你的版本返回您的實例a的副本,該副本獲得show()被調用後破壞..那破壞會破壞與a正在使用的內存相同的內存。如果您確實想要random()返回一個副本,則需要實現一個複製構造函數,該副本構造函數執行a所具有的內部列表的深層副本。

0

這不是一個「惱人的錯誤消息」,它告訴你,你的程序有不知何故損壞了內存。其實非常重要。

當您創建列表的副本時,您從不定義複製構造函數,所以最終會刪除頂層節點兩次。