2014-01-05 28 views
0

修改後我有下面的類和代碼:C++堆警告:免費堆塊就被釋放

template <class T> 
class HashTable { 

struct Pair{ 
    T element; 
    int key; 
    Pair(T element, int Key) : element(element), key(key) {}; 
}; 

int table_size; 
int counter; 
List<Pair> (*elements); 

void changeTableSize(int newSize){ 
    List<Pair> *temp = new List<Pair>[newSize]; 
    for (int i = 0; i < table_size; i++){ 
     for (typename List<Pair>::Iterator j = elements[i].begin(); j != elements[i].end(); j++){ 
      Pair p = *j; 
      temp[p.key % newSize].insert(Pair(p.element, p.key)); 
     } 
    } 
    delete[] elements; 
    elements = temp; 
    table_size = newSize; 
} 

public: 
    HashTable() : table_size(100), counter(0){ 
     elements = new List<Pair>[table_size]; 
    }; 
void insert(T data, int key){ 
    if (member(key)){ 
     throw ElementAlreadyExists(); 
    } 
    elements[key % table_size].insert(Pair (data, key)); 
    counter++; 
    if (counter == table_size){ 
     changeTableSize(table_size*2); 
    } 
}; 

當我打電話changeTableSize()的第一次,一切都很好。當我第二次調用它時,我的程序在分配temp後正好說「警告:HEAP:釋放後在006618D4修改的自由堆塊006618C0」。什麼會導致這種情況?

+0

您不能使用'elements'而無需初始化它。 –

+0

您刪除*元素*,然後將* temp *賦值給它。 – SChepurin

+0

@LuchianGrigore元素在這裏未顯示的構造函數中初始化。 –

回答

2

如果originalSize> table_size,那麼您在執行內部'for'循環中執行非法內存訪問。

刪除您傳遞給函數的'originalSize'參數。

改爲使用類變量'table_size',並在返回之前將其更新爲新大小。

此外,確保該類對具有拷貝構造適當的定義和實現:

Pair(const Pair& pair) 
{ 
    // For each variable x of pair, that points to dynamically-allocated memory: 
    // this->x = new ... 
    // memcpy(this->x,pair.x,...) 

    // For each variable y of pair, that doesn't point to dynamically-allocated memory: 
    // this->y = pair.y 
} 

否則,你可能有一流的配對指向同一個動態分配的內存內部變量的兩個不同的實例。當一個實例被銷燬時,另一個實例的內部變量將指向一個已經釋放的內存。

+0

編輯,注意構造函數。元素確實指向堆 –

+0

行,所以回答改變然後... –

+0

爲什麼做錯我做了什麼?我爲temp分配空間,刪除元素,然後告訴元素指向temp。 –