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

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  = new Node;
Node *previous = new Node;

此代码会导致内存泄漏-您永远不会删除此内存。您可以在不分配内存的情况下声明指针:
Node *current  = nullptr;
Node *previous = nullptr;
delete将删除指针的内存,因此您实际上将删除Node。
但是,使用delete[]作为Node* 是不正确的,它只能用于数组-用new[]分配的内存。使用不当会导致不确定的行为。
因此,要正确删除节点,请使用运算符删除它们删除

使用内存泄漏检测工具可以知道程序中是否存在内存泄漏。

删除列表元素的代码:例如,我们有pHead指向列表的头部
(但是如果您自己编写这样的东西,它将给您带来更多的好处):
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

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

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

确实应该在调试器中对其进行观察以查看其工作原理,但是鉴于实际发生的情况,该算法非常简单:
Node **pp = &pHead;
while (*pp && (*pp)->data != target)
    pp = &(*pp)->next;

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

到此为止。这样一来,您就可以去除头节点,而无需特殊情况下免费使用。希望这也会有所帮助。

09-09 20:44
查看更多