2013-12-09 29 views
0

我對如何正確使用delete關鍵字有點困惑。這是我的情景:C++正確使用刪除後的刪除

class Tuple { 

public: 

    Tuple(int columns); 
    ~Tuple(); 

    void set(int i, string d); 
    string get(int i); 
    int columnCount(); 

private: 

    string *data; 
    int columns; 

}; 


Tuple::Tuple(int columns) { 

    this->columns = columns > 0 ? columns : 0; 
    if (this->columns > 0) { 
     data = new string[this->columns]; 
    } else { 
     data = 0; 
    } 

} 

Tuple::~Tuple() { 
    if (columns > 0) { 
     delete[] data; 
    } 
} 

void Tuple::set(int i, string d) { 

    if (columns > 0 && i > -1 && i < columns) { 
     data[i] = d; 
    } 
} 

class Table { 

public: 

    Table(int columns); 
    ~Table(); 

    void insertTuple(Tuple t); 
    Tuple getTuple(int i); 

    int columnCount(); 
    int rowCount(); 

private: 

    vector <Tuple> data; 
    int columns; 
    int rows; 

}; 

現在,當我打電話下面的代碼,我收到了段錯誤:

 Tuple *outTuple; 
     outTuple = new Tuple(cCount); 

     for (int i=0; i<cCount; i++) { 
      tmpStr = string(reinterpret_cast<const char*>(sqlite3_column_text(statement, i))); 
      outTuple->set(i, tmpStr); 
     } 
     (*outTable)->insertTuple(*outTuple); 

     delete outTuple; //here I get segfault 

什麼是錯我的代碼?我的代碼寫得不好嗎?我可以改進它並避免段錯誤嗎?

+0

「Tuple :: Tuple(in columns)」的定義在哪裏?你真的爲'data'分配空間嗎? – suszterpatt

+0

添加構造函數和解構器以提問 –

+0

另外,爲什麼不使用std :: vector而不是數據指針?這將釋放你所有的指針麻煩... – jcxz

回答

3

最可能的原因是Tuple違反the rule of three。具體來說,你需要定義一個拷貝構造函數和一個拷貝賦值操作符。否則,你可能會雙刪除data

您不顯示構造函數和析構函數,但Tuple使用的內存管理實踐看起來很脆弱。爲什麼不使用std::vector而不是指針?

+0

非常感謝你!我添加了構造函數和解構函數來問 –

+0

@the_candyman:那麼拷貝構造函數呢?這非常重要。 –

+0

@GregHewgill我沒有定義它。關於它應該做什麼的一些建議? –

1

帶指針的動態內存分配變量通常有一個「容器」或「所有者」。

在這種情況下,函數是主要的「容器」。

「Containtment」或「Ownership」可能會轉移,例如,從函數到其他變量,在這種情況下,可能是「outTable」。

「outTable」是否從內存中刪除元組?

你打算讓「outTable」成爲元組的容器,並讓它從內存中刪除元組,而不是函數?或者,你是否打算「outTable」,只引用元組,並讓函數從內存中刪除元組。

乾杯。