我使用C ++实现了LinkedList,在处理动态分配的内存时,我似乎忘记了一些事情。
我有一个节点类:
class Node {
public:
Node(int d) {
data = d;
next = NULL;
}
Node(int d, Node* n) {
data = d;
next = n;
}
int data;
Node* next;
};
在我的LinkedList类中,我有以下方法:
void remove(int n) {
Node* current;
current = head;
Node* previous = NULL;
while ( current->data != n && current->next != NULL) {
previous = current;
current = current->next;
}
if (current->data == n) {
previous->next = current->next;
current->next = NULL;
delete current;
}
else {
std::cout << "Node not found" << std::endl;
}
}
我似乎已经忘记了......当我delete current
删除Node
时?就像指针current
指向的实际对象一样?或者只是删除指针?或者使用delete
删除指向动态分配的内存的指针是否同时删除指针和对象?或者我是否需要为此定义一个Node类析构函数?
答案 0 :(得分:2)
它只是删除结构 - 在你的案例节点 - 它指向,你仍然可以使用该指针 - 使它指向另一个节点 - 事实上,由于它&#39,它无法删除指针本身。 ; s在堆栈上分配。它会自动删除&#34;当你离开这个功能时。
p.s:无需在null
答案 1 :(得分:0)
删除指向的内存。这具有以下含义:
答案 2 :(得分:0)
假设您已使用指针上的新删除分配了对象,请执行以下操作:
在某些时候,内存管理器将释放并将其标记为进程无法访问。
因此,在将delete调用为约定值后,您可以设置指针。最好的做法是将它设置为最新编译器的nullptr。
答案 3 :(得分:0)
delete p
导致p
指向的对象不再存在。这意味着
1,如果对象有析构函数,则调用它;和
2. p
成为无效指针,因此任何取消引用它的尝试都是未定义的行为。
通常,所述对象占用的内存再次可用于程序,尽管这实际上是一个实现细节。
短语“删除指针”通常是“删除指针指向的对象”的草率简写。
答案 4 :(得分:0)
它会删除current
指向的实际结构。指针保持不变。无需定义析构函数。
delete
运算符将应用于指向对象的指针。指针是通过调用new
分配的堆上的内存地址。在内部,只有new
分配的地址表。所以释放这种内存的关键就是那个地址。在您的情况下,此类地址存储在名为current
的指向节点的类型的变量中。
您的代码中存在一些问题。有问题的是,您无法判断存储在当前的节点是否实际分配在堆上。可能会发生当前节点在堆栈上分配。 E.g。
void someFunction(LinkedList &list) {
Node myLocalNode(10);
list.add(&myLocalNode);
list.remove(10); //<-- disaster happens here
}
这同样适用于静态分配的全局变量。
你必须照顾极端的情况。想想当被删除的对象是第一个被变量head
指向时会发生什么。通过删除其内存,您最终会在head
中使用悬空指针,指向未分配的内存或其他人使用的内存。
我的第三个反对意见是写这样的结构。我希望它只是一些学校的练习,因为在任何其他情况下你应该(几乎必须)使用一些现有的列表,如C ++ STL中的std::list
。
答案 5 :(得分:0)
每当你在指针变量上调用delete
时,它所指向的对象就会从内存中删除,但是4个字节被分配给实际的指针变量(在你的情况下是current
变量),只有当变量超出范围时才会释放4个字节,即函数结束时