【问题标题】:c++ Heap warning: Free heap block modified after it was freedc ++堆警告:释放后修改的空闲堆块
【发布时间】:2021-11-30 21:32:07
【问题描述】:

我有以下类和代码:

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 后立即崩溃说“警告:堆:释放堆块 006618C0 在 006618D4 被释放后修改”。这是什么原因造成的?

【问题讨论】:

  • 你不能在没有初始化的情况下使用elements
  • 您删除 elements ,然后将 temp 分配给它。
  • @LuchianGrigore 元素在此处未显示的构造函数中初始化。
  • @StephaneRolland typename 很好。
  • @SChepurin 那我该怎么办,为什么会出现问题?

标签: c++ heap-memory


【解决方案1】:

如果 originalSize > table_size 则您正在内部“for”循环中执行非法内存访问。

删除您传递给函数的“originalSize”参数。

改用类变量“table_size”,并在返回之前将其更新为新大小。

另外,请确保类 Pair 具有正确定义和实现的复制构造函数:

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
}

否则,您可能有两个不同的类 Pair 实例,其中内部变量指向同一个动态分配的内存。而当一个实例被销毁时,另一个实例的内部变量将指向一块已经释放的内存。

【讨论】:

  • 已编辑,注意构造函数。元素确实指向堆
  • 为什么我做错了?我为 temp 分配空间,删除元素,然后告诉元素指向 temp。
  • 正确,我现在明白了。于是答案又变了。而且你还需要删除~Table()中的元素...
  • 您是否也将 'table_size' 设置为修改后答案中描述的新值?
  • 是的。 table_size = newSize
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 2015-06-15
  • 2016-05-07
  • 2017-09-06
  • 1970-01-01
  • 2011-07-23
相关资源
最近更新 更多