2014-02-21 42 views
0

當測試我的代碼時,我始終得到有關使用delete的錯誤,因爲我的類的測試臺指出刪除正在使用new []分配的數組上調用。我在我的〜IntVector中刪除了兩個擴展函數,擴展函數擴展了容量,同時爲動態分配的數組重新分配內存。不正確的解除內存分配?

如何正確使用刪除以防止內存泄漏並解決此錯誤?

主文件

#include "IntVector.h" 
#include <iostream> 
#include <vector> 
using namespace std; 


IntVector::~IntVector(){ 
    delete[] data; 
} 

void IntVector::expand(){ 
    cap = cap * 2; 
    int *data2 = data; 
    data = new int[cap]; 
    data = data2; 
    delete data2; 
    delete[] data2; 
} 

void IntVector::expand(unsigned amount){ 
    cap = amount; 
    int *data2 = data; 
    data = new int[cap]; 
    data = data2; 
    delete data2; 
    delete[] data2; 
} 

#ifndef INTVECTOR_H 
#define INTVECTOR_H 

using namespace std; 
class IntVector{ 
private: 
    unsigned sz; 
    unsigned cap; 
    int *data; 
private: 
    void expand(); 
    void expand(unsigned amount); 
}; 

#endif 
+0

我的析構函數是〜IntVector。 – user3314899

+0

您發佈了很多代碼,很難錯過所有代碼中的這樣一個小函數。你可能想閱讀[堆棧溢出問題清單](http://meta.stackexchange.com/questions/156810/stack-overflow-question-checklist)。您可能還想了解[SSCCE](http://sscce.org/)是什麼。 –

+0

@ user3314899 - 立即執行一個2行main()程序,可以讓你的班級平躺在它的臉上: 'int main(){IntVector a(10); IntVector b = a;}' 這就是你所需要的 - 你在main()的末尾有一個雙重刪除錯誤。如果我再添加兩行,我可以重現內存泄漏。正如其他人建議克服這個錯誤一樣,閱讀三條規則。 – PaulMcKenzie

回答

3

使用new[]進行分配時,必須使用delete[]。您的expand功能使用普通delete。它還包含一些其他錯誤(重新分配指針,雙重刪除等)。

你的拷貝構造函數在哪裏?複製賦值運算符?您可能想要閱讀關於the rule of three

+0

所以它會刪除[]數據而不是刪除[] data2? – user3314899

+0

@ user3314899不,至少不要開始。首先,您需要分配新數據,然後您需要將舊數據複製到新數據中,然後您需要釋放舊數據,最後您需要重新分配舊數據指針以指向新數據。 –

2

你可能會遇到這個問題,因爲你沒有遵守三個規則 - 你需要一個拷貝構造函數和賦值運算符你的班級做了很深的複製。

如果你這樣做

IntVector x(IntVector(10)); 

你會留在x懸空指針,因爲原來被解除分配時臨時IntVector(10)超出範圍。

0

除了有違反規則,你也嘗試刪除變量兩次在expand功能:

void IntVector::expand() 
{ 
    cap = cap * 2; 
    int *data2 = data; 
    data = new int[cap]; 
    data = data2; 
    delete data2; // this should not be here! 
    delete[] data2; // this will be a problem now! 
} 

只能刪除數據一次,如果你創建了一些與new[],它需要將被刪除delete[]

您的擴展功能都應該更像:

// copy-swap 
void IntVector::expand() 
{ 
    IntVector tmp; 
    tmp.reserve(cap * 2); 
    tmp.resize(sz); 
    std::copy(data, data + sz, tmp.data); 
    std::swap(*this, tmp); 
} 

// raw implementation 
void IntVector::expand() 
{ 
    unsigned int newCap = cap * 2; 
    int* newData = new int[newCap]; 
    std::copy(data, data + sz, newData); 
    delete [] data; 
    data = newData; 
    cap = newCap; 
} 

複製交換版本將讓你重新使用其他功能(析構函數,拷貝賦值運算符)和會更安全。原始實現不應修改您的內部數據元素,直到已經正確創建新的元素。這樣可以防止new中的異常使您的矢量處於不良狀態(例如cap實際上不是您的容量)。

+0

直接使用delete []時,測試設備會崩潰。我想這將是一個分配給數組的問題? – user3314899

+0

@ user3314899你必須展示一些代碼才能解釋你在說什麼。 –

+0

void IntVector :: expand(unsigned amount){cap_id = amount; int * data2 = new int [cap]; data2 = data; 刪除[]數據; * data = * data2; } – user3314899