C++ 如何正确删除C++;

C++ 如何正确删除C++;,c++,linked-list,nodes,C++,Linked List,Nodes,我感觉好像我没有真正删除节点并释放内存。我想我只是在移动指针,所以当我打印链接列表时,列表不会打印我删除的元素。所以我的问题是,我是真的在删除节点,还是只是简单地重新排列指针,使其看起来像是在删除节点(基本上只是断开链接,而不是删除节点)?谢谢你的帮助 void SLL::deleteNode(int target){ Node *current = new Node; Node *previous = new Node; for (current = front->next, prev

我感觉好像我没有真正删除节点并释放内存。我想我只是在移动指针,所以当我打印链接列表时,列表不会打印我删除的元素。所以我的问题是,我是真的在删除节点,还是只是简单地重新排列指针,使其看起来像是在删除节点(基本上只是断开链接,而不是删除节点)?谢谢你的帮助

void SLL::deleteNode(int target){
Node *current = new Node;
Node *previous = new Node;

for (current = front->next, previous = front; current != NULL; current = current->next, previous=previous->next){
    if (previous->data == target && previous == front){
        front = previous->next;
        delete[] previous;
        return;
    //This if statement deletes the element if its the front
    }

    else {

        if (previous->data == target && previous->next == NULL){
            previous = NULL;
            delete[] current;
            return;
        //This if statement deletes the node if it is the back
        }


        else if (current->data==target)
        {
            previous->next = current->next;
            delete[] current;
            return;
        //This if statement deletes a node if it is in the middle
        }
    }
    }

    delete[] current;
    delete[] previous;
}
此代码导致内存泄漏-您永远不会删除此内存。您可以在不分配内存的情况下声明指针:

Node *current  = nullptr;
Node *previous = nullptr;
delete
将删除指针的内存,因此您将实际删除节点。 但是用于
节点*
是不正确的,它应该只用于阵列-使用
新[]
分配的内存。使用不当会导致未定义的行为。 因此,要正确删除节点,请使用操作符delete删除节点

使用内存泄漏检测工具了解您的程序中是否存在内存泄漏

删除列表元素的代码:比如说,我们有一个指向列表头部的pHead (但如果你自己写这些东西,你会得到更多):


使用指针指向指针的替代方法(社区添加)

当您使用列表中的实际指针执行枚举时,上面的内容可能会有新的含义。下面从
pp
开始,分配头指针的地址(不是它指向的节点,而是实际指针本身)。我们遍历列表,直到
pp
保存指向要删除目标节点的指针的地址(可能是头指针,也可能是某个节点中的下一个
指针,没有区别)。正在寻址的指针设置为其自身节点的
next
值,然后删除目标节点

这确实应该在调试器中观察,看看它是如何工作的,但考虑到实际情况,该算法非常简单:

Node **pp = &pHead;
while (*pp && (*pp)->data != target)
    pp = &(*pp)->next;

if (*pp)
{
    Node *victim = *pp;
    *pp = victim->next;
    delete victim;
}

就这些。你可以在不需要特殊情况下免费移除头部节点。希望这也能有所帮助。

当您将
当前
上一个
声明为单个实例时,为什么要使用数组删除(
delete[]
)版本?使用
front->next
启动枚举算法与此有关。请告诉我们,您使用的不是实际不包含数据的预分配“头”节点。不需要它。除非您为节点分配了
新节点[n]
,否则您使用的
删除操作符是错误的。我不知道。我试过这个,它奏效了。请回答这个问题。不知道是什么?您的前指针是否为sentinel节点?是否为您的节点分配了vector-
new
?代码是你写的,对吗?顺便说一句,你在这个函数的开头分配的两个节点立即被泄漏,所以我可以向你保证,不管你是否删除了一个目标节点,最终都会有零内存被回收。你
delete[]
在你的第二个块中有一个空向量,但我认为控件永远无法进入那个块,所以我想这是没有意义的。谢谢。从现在起,我将不再为他们使用新的。尽管我的问题仍然存在,但如何删除目标节点?我知道你提到过它,但你能再解释一下吗?@user3291106-我提供了一个示例代码。但是如果你自己写的话,那会更有用。现在试试双链接列表,比如说,从末尾搜索。@Alex当
pHead
指向将被删除的节点时,这是如何完成的?Follow:将跳过while循环,不执行任何操作
pHead->next
将有效地分配给自身,因为
pPrev
pCur
pHead
都指向同一节点。然后使用
delete pCur销毁头部节点,从而孤立列表的整个剩余部分,并使所有三个指针保留无效、不确定的地址。一句话,哎哟。@WhozCraig谢谢你的更正!修好了。虽然我更希望用户3291106告诉我:)我不需要急于写代码,同意。@Alex没问题。看一下附录。不知道你以前是否见过它,但它值得一看。和+1表示坚持回答。
Node* pCur  = pHead;
Node* pPrev = pCur;

while (pCur && pCur->data != target) {
    pPrev = pCur;
    pCur  = pCur->next;
}

if (pCur==nullptr)  // not found
   return NOT_FOUND;

if (pCur == pHead) {   // first element matches
    pHead = pCur->next;
} else {
    pPrev->next = pCur->next;
}

// pCur now is excluded from the list

delete pCur;     // deallocate its memory
Node **pp = &pHead;
while (*pp && (*pp)->data != target)
    pp = &(*pp)->next;

if (*pp)
{
    Node *victim = *pp;
    *pp = victim->next;
    delete victim;
}