2015-12-02 37 views
0

我正在寫一個使用鏈接列表的程序,在我的代碼中,我使用「new」關鍵字創建了一個對象指針。據我所知,任何時候你使用新的關鍵字,你也需要刪除,我想知道如果我正確地做到這一點。如何正確釋放分配給鏈表的內存?

#include"gameClass.h" 
#include"card.h" 
#include"list.h" 
#include"node.h" 

using namespace std; 

List::List() 
{ 
    head = NULL; 
} 

List::~List() 
{ 
    delete head; 
} 

void List::add(Card* tmpCard) 
{ 
    if (head == NULL) 
{ 
    Node* tmpNode; 
    tmpNode = new Node; 
    tmpNode->setNext(NULL); 
    tmpNode->setData(tmpCard); 
    head = tmpNode; 
    delete tmpNode; 
} 
else 
{ 
    Node* tmpNode; 
    tmpNode = new Node; 
    tmpNode->setNext(head->getNext()); 
    tmpNode->setData(tmpCard); 
    head = tmpNode; 
    delete tmpNode; 
} 
} 

Card * List::remove() 
{ 
    if (head != NULL) 
{ 
    //Card* tmpCard; 
    Node* tmpNode; 

    tmpNode = new Node; 
    tmpNode->setNext(head->getNext()); 
    tmpNode->setData(head->getData()); 
    head->setNext(tmpNode->getNext()); 
    delete tmpNode; 
} 
    return nullptr; 
} 
+0

安裝新的'head'並立即刪除它?太糟糕了...... – MikeCAT

回答

0

你這樣做完全錯了。

  • 您將引入一個新的head然後deletehead馬上。太糟糕了。
  • 您的remove()函數幾乎沒有任何功能。它創建一個新的Node,爲它設置一些參數,然後檢索應該是相同的數據集,並且delete新的Node

試試這個:

#include"gameClass.h" 
#include"card.h" 
#include"list.h" 
#include"node.h" 

using namespace std; 

List::List() 
{ 
    head = NULL; 
} 

List::~List() 
{ 
    // delete all node currently have instead of only head 
    while (head != NULL) 
    { 
     Node* tmpNode = head; 
     delete head; 
     head = tmpNode; 
    } 
} 

void List::add(Card* tmpCard) 
{ 
    if (head == NULL) 
    { 
     Node* tmpNode; 
     tmpNode = new Node; 
     tmpNode->setNext(NULL); 
     tmpNode->setData(tmpCard); 
     head = tmpNode; 
     // do not delete the new node here! 
    } 
    else 
    { 
     Node* tmpNode; 
     tmpNode = new Node; 
     tmpNode->setNext(head); // the new head should be linked to current head, not the next node of current head 
     tmpNode->setData(tmpCard); 
     head = tmpNode; 
     // do not delete the new node here! 
    } 
} 

Card * List::remove() 
{ 
    if (head != NULL) 
    { 
     //Card* tmpCard; 
     Node* tmpNode; 

     // no creating new nodes to remove the first node 
     tmpNode = head->getNext(); // remember where the next node is 
     delete head; // remove the head 
     head = tmpNode; // move the head 
    } 
    return nullptr; 
} 

UPDATE:如果你想指針返回卡在節點被移除時,remove()功能將是這樣的:

Card * List::remove() 
{ 
    if (head != NULL) 
    { 
     Card* tmpCard; 
     Node* tmpNode; 

     tmpCard = head->getData(); // remember where the card pointed by head is 
     tmpNode = head->getNext(); // remember where the next node is 
     delete head; // remove the head 
     head = tmpNode; // move the head 
     return tmpCard; // return the card 
    } 
    return nullptr; // there are no cards in this list 
} 
+0

因此,刪除設置爲返回一個卡片指針,以便我可以將每個移除的卡片以隨機順序放入另一個鏈接列表(FILO)中。我創建了新的Node,因此我可以在指針被刪除之前返回它,這是否是錯誤的方式來完成這項任務? –

+0

你想退貨嗎?但你不回報它。另外,你想返回一個卡片指針,所以返回一個卡片指針,不是指向'Node'的指針,也不是創建新的'Node'。 – MikeCAT

+0

感謝您的幫助。我跟着你的第一個例子,結束了你的第二個例子,同時找出如何返回我所需要的 –

0

要避免此問題,只需使用std::shared_ptr<Node>即可。只要指針超出範圍,指針就會釋放它指向的內容(如果沒有其他共享指針指向它)。

如果您確實想要練習使用new/delete,您會誤解它的作用:使用new創建新節點,然後以某種方式使用該節點。只有當節點不再需要時,你纔會刪除它。現在發生以下情況:

Node* tmpNode; 
tmpNode = new Node;  // You get a new Node on heap. 
tmpNode->setNext(NULL);  
tmpNode->setData(tmpCard); 
head = tmpNode;   // Head now points to the new Node. All is well. 
delete tmpNode;   // The Node both tmpNode and head point to is deleted! 

現在,head和tmpNode都包含一個指向未分配內存的指針。當你訪問它時,你會得到未定義的行爲。你可能想要的是刪除List的析構函數中的所有節點,以及其他任何地方。

+0

謝謝你在我的代碼中的評論,這是非常有幫助的! –