2010-12-03 45 views
0

我試圖讓運營商超載的感覺,但遇到了問題。該方案只是爲了避免兩個字符串。我知道還有其他方法可以做到這一點,但我想玩。我得到以下錯誤:重載+類內部 - 調試斷言失敗!

文件:dbgdek.cpp 行:52 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse));

我認爲這與我使用delete []有關。請幫助我真的被卡住了。

#include <iostream> 
using namespace std; 

class list{ 
public: 
char *value; 
int size; 
list(int s){size=s; allocmem();}; 
~list(){delete [] value;}; 
list operator+(list); 
private: 
void allocmem(void); 
}; 

void list::allocmem(void){ 
value=new char[size]; 
} 

list list::operator+(list a) 
{ 
list t(a.size+size); 
for (int i=0; i<a.size; i++){ 
     t.value[i]=a.value[i]; 
} 
for (int i=a.size; i<t.size; i++){ 
     t.value[i]=a.value[i-a.size]; 
} 
return t; 
} 

int main() 
{ 
    list a(2),b(2),c(4); 
    a.value[0]='a'; 
    b.value[0]='b'; 
    a.value[1]='c'; 
    b.value[1]='d'; 
    c=a+ b; 
    for (int i=0; i<c.size; i++){ 
      cout<<c.value[i]; 
    } 
    system("pause"); 
    return 0; 
} 

請幫忙!

回答

0

你需要做兩件事情:

  1. 創建,通過參考,並不值
  2. 通過創建自己的數據副本拷貝構造函數。

您正在通過價值operator +()。這將通過對象的副本(不是你想要的;你想傳遞一個引用)。但是,因爲您沒有創建複製構造函數,所複製的對象會獲得默認的逐個成員副本 - 現在2個對象具有相同的指針。第一個刪除它很好,第二個對象現在有一個無效的指針。

1

第一個警告標誌:你的類的析構函數執行一些delete ing,但該類未定義複製構造函數或複製賦值運算符。

查看Rule of Three

您可能會意外地創建對象的臨時副本,並在調用臨時析構函數時將其搞亂。

1

您需要爲類定義賦值運算符(list::operator=(list const&))和複製構造函數(list::list(list const&)),以避免在析構函數中重複刪除內存。如果您沒有定義這些函數,編譯器將使用這些函數的默認生成版本,這本質上會創建列表對象的按位副本。在複製列表實例後,這是災難性的,兩個實例將具有相同的指針值,導致重複刪除。

0

而不是直接使用char*字符串,爲什麼不使用std::string?那麼你不必擔心內存管理問題(在這種情況下,由於沒有像其他人指出的那樣執行復制構造函數,所以出現了雙重刪除)。在最直譯,這將是這樣的:

class list 
{ 
public: 
std::string value; 
int size; 
list(int s){size=s; allocmem();} 
~list(){} 
list operator+(list); 
private: 
void allocmem(void); 
}; 


void list::allocmem(void){ 
value.resize(size); 
} 

注意,幾乎肯定使用string更常更好的實現(例如size可以走)。另外你可能不應該有你所有的屬性public