2017-08-10 49 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)'會產生一個自動變量。這就是我所錯過的。 –