如何识别对象是在栈内存还是堆内存

问题描述 投票:0回答:1

我最近收到了一份数据结构课程的大学作业,要求我用 C++ 创建一个双向链表。我想开门见山。在处理我的双向链表时,我需要实现各种功能,但特别引起我注意的一种方法是“clear()”。该方法负责清除双向链表中的所有元素 void clear(Node* head_ptr) { Node* previous_ptr = nullptr; while(head_ptr != nullptr) { previous_ptr = head_ptr; // Store previous node. head_ptr = head_ptr->next; delete previous_ptr; } };

方法非常简单;它只是迭代所有元素并为每个节点释放内存。然后我
在我的析构函数中

调用此方法,如下所示: ~List() { clear_list(m_head_ptr); };

然后我开始思考。这种释放内存的方法很好
如果我的节点元素位于堆上

,如下所示: int main() { List list; Node* node_1 = new Node(3, nullptr); // The tail node. Node* node_2 = new Node(1, node_1); Node* node_3 = new Node(5, node_2); Node* node_4 = new Node(7, node_3); // The head node. list.add(node_1); list.add(node_2); list.add(node_3); list.add(node_4); // Then do some stuff with the list... } // The list goes out of scope and the destructor is called...

但是,一旦我创建
堆栈上的节点

并将指针传递给堆栈对象,就会中断,如下所示: int main() { List list; Node* node_1(3, nullptr); // The tail node. Node* node_2(1, node_1); Node* node_3(5, node_2); Node* node_4(7, node_3); // The head node. list.add(&node_1); list.add(&node_2); list.add(&node_3); list.add(&node_4); // Then do some stuff with the list... } // The list goes out of scope and the destructor is called and the program crashes because it attempts to free stack objects...

原因是
因为我正在尝试释放堆栈对象,这不是一个好主意

。当然,我们通常不会使用基于堆栈的节点,因为我们通常希望节点数据在它们创建的范围之外持续存在。尽管如此,这还是让我想到了我的问题: 我该如何应对? (有没有办法检查

内存中的某个节点是否在我的函数中的堆或堆栈上

,然后相应地释放它?或者是否有更好的方法来解决这个问题?)

c++ list memory stack heap
1个回答
1
投票
通常

让列表来管理节点本身的分配。用户甚至不需要知道 node 类型的存在,更不用说分配它们等等。

因此,对于用户来说,您在问题中显示的内容相当于:

List list; list.add_head(1); list.add_head(3); list.add_head(5); list.add_head(7);

您通常还可以使用 
add_tail

将项目添加到列表末尾。每个

add
(头或尾)通常应该返回一个抽象
iterator
类型(它可能是指向节点的指针的包装器),因此您可以执行以下操作:
auto pos = list.add_head(7);
list.add_tail(5);
list.add_after(pos, 3);

...这会在开头添加 7,在结尾添加 5,并在 
3

之后添加

7
这样,列表本身就分配了所有节点,并知道如何处置它们。您可以更进一步,将分配和处置委托给 

Allocator

类。这当然很有用,但可能有点超出了基本练习的意义(在实际使用中,您可能想使用标准库中的容器——虽然标准库确实提供了单向和双向——链表,它们

很少
有用)。

© www.soinside.com 2019 - 2024. All rights reserved.