2014-03-01 68 views
0

我感觉好像我并没有实际删除节点并释放内存。我想我只是移动指针,所以当我打印链表时,列表不会打印出我删除的元素。所以我的问题是我实际上是删除节点还是我只是简单地重新安排指针,所以它看起来像我删除节点(本质上只是打破链接,但不删除节点)?感谢您的任何帮助。如何正确删除C++中链接列表的节点

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; 
} 
+0

当你将'current'和'previous'声明为单个实例时,为什么要使用数组delete?('delete []')版本? – mathematician1975

+0

用'front-> next'开始你的枚举算法是关键的。 *请*告诉我们您没有使用实际不包含数据的预分配“头”节点。这不是必需的。除非你用'new Node [n]'分配你的节点,否则你使用错误的'delete'操作符。 – WhozCraig

+0

我不知道。我试过这个工作。请回答这个问题。 – WombatCombat

回答

5
Node *current = new Node; 
Node *previous = new Node; 

此代码会导致内存泄漏 - 你永远不会删除这个内存。您可以在不分配内存声明指向:

Node *current = nullptr; 
Node *previous = nullptr; 

delete将删除指针的内存,所以你会真正删除节点。 但使用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值,然后目标节点被移除。

这真的应该在调试器中观看,看看它是如何工作的,但该算法是非常简单的给出什么是怎么回事:它

​​

所有。你可以免去头节点的移除,而无需特殊情况。希望这也有帮助。

+0

谢谢。从现在开始,我不再使用新的。虽然我的问题仍然存在,但我如何删除我的目标节点?我知道你已经触及了它,但是你能否再解释一下。 – WombatCombat

+0

@ user3291106 - 我提供了一个示例代码。但是你自己写它会更有用。现在尝试双链表,并从最后搜索。 –

+0

@Alex当'pHead'指向将被删除的节点时,它如何完成?遵循:while循环将被跳过,什么都不做。由于'pPrev','pCur'和'pHead'都指向同一个节点,所以'pHead-> next'将被有效地分配给它自己。然后,头节点将被删除'delete pCur;',从而孤立整个列表的剩余部分,并使所有三个指针保持一个无效的,不确定的地址。总之,* ouch *。 – WhozCraig