c++ - 如何释放C++类中静态指针指向的内存

标签 c++ pointers memory memory-leaks static

#pragma once // Link.h

#include <memory>
template <typename E>
class Link
{
private:
    static Link<E> * freelist; // Pointer to the freelist head
                              // How to release the memory??

public:
    E element;
    Link *next;

    Link(const E &eleval, Link *nextval = nullptr)
        : element(eleval)
        , next(nextval) {}
    Link(Link *nextval = nullptr) : next(nextval) {}

    /*~Link()
    {
        while (freelist->next != nullptr)
        {
            Link<E> *tmp = freelist;
            freelist = freelist->next;
            delete tmp;
        }
    }
*/
    void *operator new(size_t)
    {
        if (freelist == nullptr) return ::new Link;
        Link<E>* temp = freelist;
        freelist = freelist->next;
        return temp;
    }

    void operator delete(void* ptr)
    {
        ((Link<E>*)ptr)->next = freelist;
        freelist = (Link<E>*)ptr;
    }
};

template <typename E>
Link<E>* Link<E>::freelist = nullptr;

Link 类中有一个静态指针,用于存储我的链表中的freelist,我想在程序结束后释放这个freelist 的内存。我怎样才能删除这个空闲列表的内存。

PS:我试过这样释放内存:

/*~Link()
    {
        while (freelist->next != nullptr)
        {
            Link<E> *tmp = freelist;
            freelist = freelist->next;
            delete tmp;
        }
    }
*/

但程序无故终止。

最佳答案

But the program terminated for no reason.

让我们看看这个循环。在这里你删除项目:

delete freelist;

然后,在你删除它之后,你在循环条件中访问它:

while (freelist->next != nullptr)

这是未定义的行为。您正在访问您删除的元素。我建议改为进行递归,遍历列表并在退出时删除元素。也许像

/** Delete a link and all the ones after it as well */
void recursiveDelete()
{
    if (next){
        next->recursiveDelete();
    }
    delete this;
}

然后在 freelist 上调用它。此外,您需要删除以下重载:

void operator delete(void* ptr)
    {
        ((Link<E>*)ptr)->next = freelist;
        freelist = (Link<E>*)ptr;
    }

所以如果我没理解错的话,当你删除一个 Link 时,你设置了链接的 next (它无论如何都会被删除,所以什么都不做) 然后将 freelist 设置为现在将变为无效的链接。这会使删除项目变得困惑。

正如 Christophe 所指出的,删除这样一个大列表可能会导致堆栈溢出。通过使用不使用递归的算法可以避免这种情况。你可以尝试这样的事情:

/** Delete a link and all the ones after it as well */
void deleteAll()
{
    std::vector<Link*> links;
    Link* toDelete = this;
    while (toDelete) {
        links.push_back(toDelete);
        toDelete = toDelete->next;
    }
    for (Link* i : links) {
        delete i;
    }
}

关于c++ - 如何释放C++类中静态指针指向的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52733908/

相关文章:

c - 棘手的 C 字符指针问题

c - 将混合类型的结构传输到不同内存位置的相同结构

c++ - 内存错误c++ private int

c++ - C++ 中的特定内存管理问题

c++ - serpent加密 key 表,如何通过 key 扩展至256位

c++ - 指针声明

c - 为什么当我们返回本地地址而不是本地变量时会产生运行时错误?

c - 如何在 Linux 内核中为 char* 类型的字符串分配内存?

c++ - 尝试在 avl 树中实现查找

c++ - 如何使用构造函数中的参数调用 C++ 中另一个类的构造函数?