2011-09-30 73 views
0

我对C++比较陌生,我遇到了一个我实际上不理解的问题。我的代码创建一个链表。它实际上比这更长,但为了这个问题我砍了下来。C++删除操作符

当我运行的代码,它增加了三个节点,然后当它与URI b删除的节点,它调用delete运营商和最终删除节点,但随后似乎回到delete操作(当我通过它时),它杀死了我的整个列表。

#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <cstdio> 

using namespace std; 


class CLinkedList 
{ 
protected: 
    class ip_uri_store 
    { 
    public: 
     string uri, ip; 
     ip_uri_store* next; 

     ip_uri_store(const string& URI, const string& IP) {uri = URI, ip = IP, next = NULL;} 
    }; 
    typedef ip_uri_store* nodeAddress; 

    nodeAddress head; 

    void AddNode(const string&, const string&, nodeAddress); 
    void DeleteNode(const string&, nodeAddress, nodeAddress); 

public: 
    CLinkedList() {head = NULL;} 
    void AddNode(const string& URI, const string& IP) {AddNode(URI, IP, head);} 
    void DeleteNode(const string& URI) {DeleteNode(URI, head, head);} 

}; 

void CLinkedList::AddNode(const string& URI, const string& IP, nodeAddress node) 
{ 
    nodeAddress temp = new ip_uri_store(URI, IP); 
    temp->uri = URI; 
    temp->ip = IP; 
    temp->next = head; 
    head = temp; 
} 

void CLinkedList::DeleteNode(const string& URI, nodeAddress node, nodeAddress behindNode) 
{ 
    if(node) 
    { 
     if(!node->uri.compare(URI)) 
      node == head ? head = head->next : behindNode->next = node->next; 
     else 
      DeleteNode(URI, node->next, node); 

     delete node; 
    } 
} 



int main(int argc, char* argv[]) 
{ 
    CLinkedList lList; 
    lList.AddNode("a", "1"); 
    lList.AddNode("b", "2"); 
    lList.AddNode("c", "3"); 
    lList.DeleteNode("b"); 

    return 0; 
} 
+5

即三元条件运算符的严重滥用。 –

+1

考虑到他是新手,代码似乎从随机站点复制... – Blindy

+0

我没有复制它。这是我的代码。新的我的意思是几个月。我一直在阅读很多关于C++的知识... –

回答

3

要调用delete node;即使比较失败(即node->uri != URI)。

if(!node->uri.compare(URI)) 
{ 
    node == head ? head = head->next : behindNode->next = node->next; 
    delete node; 
} 
else 
    DeleteNode(URI, node->next, node); 

此外,条件似乎是倒置的。

+0

非常感谢。递归困惑了我。我没有意识到它在else部分中调用了DeleteNode,运行了delete,并在返回到调用函数时重新调用它。再次感谢! –

+0

没有得到“重新调用”。递归不是魔术:你只是在执行一个函数调用,就像其他任何函数一样。函数调用完成后继续执行。 –

+0

@ user968243,你应该尝试重写这个,而不递归。作为一般的经验法则,您应该只对可以保证有限高度的树进行递归。尝试检查URI,如果比较失败,则将'node'分配给其后继者并重复(使用'while'这样的循环结构)。 – avakar

0

您正在调用所有节点上的删除。它需要有条件内移动,就只删除节点相匹配的URI

if(!node->uri.compare(URI)) { 
    node == head ? head = head->next : behindNode->next = node->next; 
    delete node; 
} else { 
    DeleteNode(URI, node->next, node); 
} 
1

首先,你应该使用std ::列表,并避免重复的世界。 无论如何,如果你因为某种原因而坚持这个实现:

  • temp-> uri = URI;和temp-> ip = IP;在AddNode方法中是无用的,因为成员已经在ip_uri_store类的构造函数中初始化。
  • 由于删除节点只能在DeleteNode方法的情况node-> uri.compare(URI)中完成,因此删除了列表头部。

再次,你应该认真考虑使用标准类...

+0

我知道关于std :: List;但是,我必须使用类和递归来实现链表。不过将来,我会使用std :: List。谢谢你指出不必要的分配。 –