template<typename T>
T& List<T>::popFront()
{
if (head == NULL)
throw std::underflow_error("List error: no head node available\n");
if (tail == head)
tail = NULL;
T item = head->item;
head = head->next;
return item;
}
我有一个具有以下字段的递归结构 ListNode:
template <typename T>
struct ListNode {
T item;
ListNode* next;
...
}
问题是我想在 popFront 过程之后释放一个头节点,但是由于所有嵌套节点都间接指向同一个地址,它们的地址也从堆中消失了。所以现在,正如您在上面看到的,我只是将头节点的指针地址更改为下一个头节点,我认为这会导致内存泄漏。
我不排除我对这种方法和我的假设完全错误。如果确实需要重新分配,请考虑执行此类任务的最有效方法。
最佳答案
这里有几个问题。
template<typename T>
T& List<T>::popFront()
{
if (head == NULL)
throw std::underflow_error("List error: no head node available\n");
if (tail == head)
tail = NULL;
T item = head->item;
head = head->next; //Memory leak, you just lost your only pointer to the head item
return item; //Returning reference to stack variable, undefined behavior
}
我会建议您将签名更改为按值返回,这样您就可以返回本地并释放堆中的元素。
template<typename T>
T List<T>::popFront()
{
if (head == NULL)
throw std::underflow_error("List error: no head node available\n");
if (tail == head)
tail = NULL;
T item = head->item;
ListNode* old_head = head; //keep this for deallocation
head = head->next;
delete old_head; //Deallocate the old head
return item; //Return by value
}
当然,您可以采用 std::list
的行为并有不同的访问和弹出方法,front()
和 pop_front()
分别。
根据签名,front()
返回一个引用,如果 T
是一个重对象,这会更有效。
当然,这一切都假设您是出于学术目的而进行的。否则,好吧,使用 std::list
或类似的标准库容器。
关于c++ - 释放指向保留嵌套变量内存地址的结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45374096/