2017-08-10 48 views
4

我有一个链接列表类的简单实现,它具有指向我也已定义的节点对象的指针。C++构造函数似乎每次都返回指向同一对象的指针

函数insertHead创建一个新节点并将其插入到头部。然而,每当我调用该函数时,构造函数似乎每次都会返回一个指向同一对象的指针。 (我检查了使用GDB)

我正在粘贴这里的代码片段。有人可以让我知道,如果有什么似乎关闭?

void LinkedList::insertHead(int val){ 
    Node temp(val); 
    if(head == NULL){ 
    head = tail = &temp; 
    } else { 
    temp.setNext(head); 
    head = &temp; 
    } 
} 

类定义:

class LinkedList{ 

    Node *head; 
    Node *tail; 
... 

class Node{ 

    int val; 
    Node *next; 
... 

Node::Node(int x){ 
    val = x; 
    next = NULL; 
} 
+1

'temp',正如你正确命名它,有自动生命周期:你正在存储指向死对象的悬挂指针。 – Quentin

+3

您正在保存一个指向局部变量的指针,该变量超出了范围,并在该函数结束时变为无效。指针是一个指向堆栈的指针,所以它可能每次都是一样的。如果您需要动态分配对象,请使用'new'或某种唯一或共享的指针。 –

回答

1

automatic storage分配地址变量,并用它在身体外面,becouse它得到了超出范围(undefined behaviour)。您需要为node动态分配heap上的空间。

Node * temp = new Node(val); 
if(head == NULL) 
{ 
    head = tail = temp; 
} else { 
    temp.setNext(head); 
    head = temp; 
} 

并在析构函数中释放所有节点。

1

您需要在堆而不是堆栈分配的节点。 (我鼓励你阅读这两篇文章)。也请使用nullptr代替NULL如果支持的话(> C++ 11)

void LinkedList::insertHead(int val){ 
    Node* temp = new Node(val); 
    if(head == nullptr){ 
    head = tail = temp; 
    } else { 
    temp->setNext(head); 
    head = temp; 
    } 
} 

这也将需要你清理的节点使用delete正确,以避免内存泄漏,这将很可能需要增加一个自定义的析构函数您的列表类的东西沿着这些线路:

LinkedList::~LinkedList() { 
    Node* node = head; 
    while(node != nullptr) { 
    Node* toDel = node; 
    node = node->next; 
    delete toDel; 
    } 
} 
+0

谢谢。我没有得到'Node temp(val)'会产生一个自动变量。这就是我所错过的。 –