我正在经历一些练习编码的问题,我遇到了一个-
实现一种算法来删除单个链表中间的节点,只允许访问该节点。
示例:
输入:链表a->b->c->d->e
中的节点"c"
结果:没有返回任何内容,但新的链表看起来像a->b->d->e
解决方案是简单地将数据从下一个节点复制到此节点,然后删除下一个节点。
上述解决方案将java作为编程语言牢记在心。我想知道被删除节点的内容会发生什么?它在java和c++中的命运会有所不同吗?而且,我认为这个问题的完美答案还应该释放被删除节点的内存。我们如何在c++中做到这一点?
还应解除分配已删除节点的内存。
是的。
我们如何在c++中做到这一点?
使用delete
运算符。
如果你正在处理链接列表,而不了解delete
运算符,你可能会超越自己。学习C或C++时,你不想跳过步骤;它稍后会咬掉你的头。
在Java中,内存最终可以由垃圾收集器释放。无法保证何时(因此也无法保证是否)会发生这种情况。(在实践中,这种情况通常会很快发生)。
在带有智能指针的C++中,一旦对象无法再寻址,就保证了内存的释放。实际上,只要没有任何循环引用图,它的工作方式就很像Java中的垃圾收集。
如果不使用智能指针,则必须手动调用delete c
(或free(c)
)。如果你不这样做,你的程序将分配内存,再也不能使用了。
好吧,这并不完全是您在C++中所做的。你应该做什么/会发生什么:
- 删除
c
指向的内存 - 将指向内存的指针从
d
复制到c
- 将指向
e
的指针从d
复制到c
现在,我们有效地将d
从列表中删除,并使c
表现得像d
。最后,如果d
本身也被分配到某个地方,并且必须单独删除,则在3之后删除它。
为什么是1?因为在Java中,如果一个对象不再使用,它就会自动被垃圾回收。在C++中,情况并非如此。
在回答题为"C++中未使用的内存会发生什么"的问题时,内存管理器将内存标记为未分配,但为了提高效率,此时(如果有的话)可能不会返回操作系统。通过删除关键字进行解除分配
对于您的具体示例(匆忙拼凑而成):
假设一个节点,如
struct Node
{
Node* next;
} head;
//Later...
Node* pred = head; //Where head is the start of the list
while((pred->next != NULL) && (pred->next != c))
{
pred = pred->next;
}
Node* toDelete = pred->next;
Node* newSuccessor = toDelete->next;
/*
This is the moment when the memory is considered freed.
free() should only be used if the node was allocated with malloc()
*/
delete toDelete;
pred->next = newSuccessor;
在Java中,它最终会被收集为垃圾。在C++中,您必须使用delete
关键字显式地解除分配它。
一旦释放了内存,实际的位将保持不变,但可能随时被重新分配和覆盖。