#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/