2012-09-11 31 views
1

這一直在摧毀我。我敢肯定有一個原因:與對象一起返回時清除內存指針

chain operator+(chain c) 
{ 
    chain<Object> result; 
    for (int i = 0; i < length(); i++) 
    { 
     result.insert(*(Object*)(memory+(i*sizeof(Object)))); 
    } 
    for (int i = 0; i < c.length(); i++) 
    { 
     result.insert(c[i]); 
    } 
    for (int i = 0; i < result.length(); i++) // This for loop successfully shows all objects in result 
    { 
     cout << result[i]; 
    } 
    return result; 
} 

當返回值,即:

chain<int> a; 
cin >> a; // enter "5 6 7 8" 
chain<int> b; 
cin >> b; // enter "9 10 11 12" 
chain <int> c = a+b; 

cout << c; // Returns "0 0 7 8 9 10 11 12" 

前兩個數字是始終爲0。我想不通爲什麼。這隻在將兩條鏈連在一起時纔會發生;如果我選擇a或b,我會得到所有的價值。

我真的如果任何人有任何的信息共享欣賞它:)

編輯**

全部來源

#ifndef CHAIN_H 
#define CHAIN_H 

#include <iostream> 
#include <stdlib.h> 

using namespace std; 

template <class Object> 
class chain 
{ 
    public: 
      chain(){ 
        memorySize = 8; 
        memory = calloc(memorySize, sizeof(Object)); 
        count = 0; 
      } 
      chain(Object item){ 
        memorySize = 8; 
        memory = calloc(memorySize, sizeof(Object)); 
        count = 0; 
        insert(item); 
      } 
      chain(chain & original){ 
        memorySize = 8; 
        memory = calloc(memorySize, sizeof(Object)); 
        count = 0; 
        for (int i = 0; i < original.length(); i++) 
        { 
          insert(original[i]); 
        } 
      } 
      ~chain(){ 
        free(memory); 
      } 
       chain operator+(chain c){ 
        chain<Object> result; 
        for (int i = 0; i < length(); i++) 
        { 
          result.insert(this->operator[](i)); 
        } 
        for (int i = 0; i < c.length(); i++) 
        { 
          result.insert(c[i]); 
        } 
        for (int i = 0; i < result.length(); i++) 
        { 
          cout << result[i]; 
        } 
        return result; 
      } 
      Object & operator[](int pos){ 
        return *(Object*)(memory+(pos*sizeof(Object))); 
      } 
      int length(){ 
        return count; 
      } 
      void insert(Object item){ 
        if (count == memorySize) 
        { 
          doubleMemory(); 
        } 
        this->operator[](count) = item; 
        count++; 
      } 
    private: 
      int count; 
      int memorySize; 
      void * memory; 
      void doubleMemory(){ 
        memorySize *= 2; 
        memory = realloc(memory, (memorySize*sizeof(Object))); 
      } 

}; 
template <class Object> 
ostream& operator<<(ostream& out, chain<Object>& c){ 
    for (int i = 0; i < c.length(); i++) 
    { 
      out << c[i] << " "; 
    } 
} 
template <class Object> 
istream& operator>>(istream& in, chain<Object>& c){ 
    char ch; 
    int number = 0; 
    int sign; 
    while(ch != '\n') 
    { 
      ch = in.get(); 
      if (ch == '-') 
      { 
        sign = 1; 
      } 
      else if (ch >= '0' && ch <= '9') 
      { 
        number *= 10; 
        number += (ch-48); 
      } 
      else if (ch == ' ' || ch == '\n') 
      { 
        number = sign == 1? 0 - number : number; 
        c.insert(number); 
        sign = 0; 
        number = 0; 
      } 
    } 
} 
#endif 

下面是我測試對代碼:

#include "chain.h" 

using namespace std; 

int main(){ 

    chain<int> a, b, c; 
    chain<int> d(10); 
    chain<int> e(d); 
    cin >> a; 
    cout << endl; 
    cout << endl; 
    c = a+d; 
    cout << c; 
} 

+1

問題可能不在'運算符+'中,它可能在您的副本c'tor或'operator <<'中。你可以發佈這些呢? – StoryTeller

+1

如果您提供了重現此行爲的完整示例,則可能會獲得更多幫助。 –

+1

Luchian刪除了他的答案 - 但是我不會*使用他的'this-> operator [](i)'的解法......太複雜的語法。改用'(* this)[i]'。 –

回答

3

您顯示的代碼不是問題。真正的問題可能在於複製構造函數或chain的析構函數 - 也可能在insert方法中(或者在C++ 11中,在移動構造函數中)。

(這也可能是在Object的拷貝構造函數,但我認爲這是不可能的。)


編輯:噢,我的。不要在C++中編寫這樣的代碼。這是不安全的左,右和中心。只要Object是一個POD,你應該沒問題,但如果不是這種代碼會產生未定義的行爲。特別是,它不會爲您存儲在鏈中的對象調用正確的構造函數和析構函數。

此外,由於您沒有修改傳入的chain,因此您的副本構造函數應接受類型爲chain const&的參數。這又要求您通過提供operator []的適當const超載來使您的類正確無誤。

最後和最明顯的是,您違反了三條規則,因爲您沒有爲您的chain實施operator =。試圖將一個chain分配給另一個將導致雙重釋放。

一般應避免callocfree和使用標準的容器而不是,或者,如果這不是一個選項,使用new[]加上像boost::shared_array智能指針來管理內存(但使用delete[])。

另一件事,從不在頭文件中使用using namespace,它會污染命名空間並導致最奇怪的地方的名稱衝突。

+0

是的,確實如此。好像**三規則**沒有得到正確遵守。也許,三巨頭之一的錯誤。 –

+0

我已更新完整來源。試圖挖掘其他的東西,看看我錯過了什麼... – user1662285

+0

更新我的代碼與您建議的更改。感謝您的建議。 – user1662285

0

嗯,我看到以下關於複製構造函數的問題。在我看來,你想這樣做的複製構造函數:

chain(chain & original){ 
    memorySize = 8; 
    memory = calloc(memorySize, sizeof(Object)); 
    count = 0; 
    for (int i = 0; i < original.length(); i++) 
    { 
     insert(original[i]); 
    } 
} 

但它不能因爲該方法的聲明是錯誤的。您在複製參數中缺少const修飾符。如果不包含它,編譯器會假定您只聲明瞭一個可變引用的正常構造函數,並且這不是您需要在 Rule of Three之後定義的複製構造函數。

只要改變這一點:

chain(chain & original){ 

這樣:

chain(const chain & original){ 

這可能會解決一個錯誤的內存處理,並希望你會得到你的程序不同的輸出。

+0

這只是問題的一小部分,它在康拉德魯道夫的回答中提到了很長一段時間:( – codeling

+0

是的康拉德魯道夫的答案是更完整的,沒有看到它的時間我寫了我的。 –

相關問題