【问题标题】:Memory leak in Hashtable/Doubly linked listHashtable/双向链表中的内存泄漏
【发布时间】:2016-09-02 16:50:05
【问题描述】:

我正在为我的 CS 课程工作,我们正在开发自己的简单哈希表实现。为此,我创建了多个类:

  • Liste(这是一个双向链表)
  • 哈希表(这是一个简单的哈希表,具有灵活的槽数)
  • Tester(这是一个测试类,它计算键比较并将它们打印到 csv 文件中以用于一系列案例)

测试器为每次运行生成一个新的哈希表。例如,当我为每次运行执行 100 次运行测试时,将在删除旧的哈希表后创建一个新的哈希表。这是必需的,因为测试的槽数通常会发生变化。

在哈希表的每个槽中都有一个指向双向链表的指针,它是在哈希表的构造函数中创建的。该列表提供了用于插入值、查找值、获取最后一次搜索的键比较和清除所有元素的方法。析构函数调用清除双向链表中所有元素的方法。析构函数在运行结束时被调用,我用调试消息检查了它。我还尝试检查是否从我之前创建的内存中清除了相同数量的元素,但引用计数总是合适的。

我的问题是每次运行测试仪后都会分配更多内存。如果您在哈希表中执行大量运行或运行大量元素,这将是一个真正的问题,因为它需要兆字节或千兆字节的内存。

我的 IDE 是 OS X 上最新版本的 Xcode。我使用 Instruments(分析工具)来查找泄漏代码,但它只是建议查看我的 add-method。

    void Liste::add(int key, int wert)
    {
        Element *createdElement = new Element();
        this->referenceCount++;

        createdElement->wert = wert;
        createdElement->key = key;

        if(this->head == NULL && this->tail == NULL)
        {
            this->head = createdElement;
            this->tail = createdElement;
        }
        else
        {
            tail->next = createdElement;
            createdElement->prev = this->tail;
            this->tail = createdElement;
        }

        this->size++;
    }

当然这是分配内存的地方,但是我的 clear-method 稍后应该在游戏中被析构函数触发时删除所有这些元素:

    void Liste::clear()
    {
        cout << "Liste::clear() is fired." << endl;
        Element *cursor = this->head;

        while (cursor != NULL)
        {
            if(cursor->prev != NULL)
            {
                delete cursor->prev;
                cursor->prev = NULL;
                this->referenceCount--;
            }

            cursor = cursor->next;
        }

        delete cursor;
        this->referenceCount--;

        this->head = NULL;
        this->tail = NULL;
        this->size = 0;
    }

在 Instruments 告诉我 add-method 是唯一分配内存但在使用后没有释放的地方之后,我希望你能帮助我解决这个内存泄漏问题。我有一些使用多种编程语言的经验,但是在我不得不用 C++ 编写代码之前,我从来没有在内存管理方面遇到过这么大的麻烦。

【问题讨论】:

  • 没有足够的信息来提供有意义的帮助,但请考虑删除您的 clear 函数以支持一个 clear 函数,该函数重复调用您的链表的删除/擦除函数,直到列表为空。有两个工具可以帮助您:开发环境附带的调试器在运行时单步执行您的列表代码,以及 valgrind 寻找丢失的Elements。至于内存管理,C++ 的强大功能确实是有代价的。

标签: c++ memory memory-management memory-leaks


【解决方案1】:

看起来您永远不会删除最后一个游标,因为它的上一个游标将为空。 如果(光标->上一页!=空) ... 别的 删除光标;休息;

您也不需要其他删除游标调用,因为它始终为空。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2017-09-26
    • 1970-01-01
    相关资源
    最近更新 更多