0

我寫了這個函數,將另一個鏈表插入到現有鏈表中。當我輸出函數中的「this」對象的值時,輸出是正確的。但是,程序在最後調用析構函數時會遇到運行時錯誤。我認爲運行時錯誤是由於有2個指針指向相同的地址造成的;因此當一個人被分配時,另一個人成爲懸掛指針。在鏈表中插入一個鏈表

有什麼辦法可以插入另一個鏈接列表到現有的鏈接列表(在中間),而不會導致這個問題?

void List::insert(const List& otherList, const int &index) 
{ 
    Node* insertion = head; 
    int x = index; 
    while (x > 0){ 
     insertion = insertion->next; 
     x--; 
    } 

    if (index == 0){ //this works fine 
     otherList.tail->next = insertion; 
     *this = otherList; /*I implemented a copy ctor 
           that performs deep copy 
           so this is also fine */ 
    } 
    else{ // this block causes problems 
     Node* tmp = insertion->next; 
     insertion->next = otherList.head; 
     otherList.tail->next = tmp; 
    } 
    cout << "after the copy\n" << (*this) << endl; 
} 
+1

插入後,這兩個列表引用相同的節點,這就是爲什麼你的代碼崩潰。一個析構函數釋放共享節點,然後另一個析構函數嘗試再次釋放它們。您需要從源列表中物理刪除節點,以使它們僅存在於目標列表中,否則您需要深度複製節點的* data *並且不要複製節點指針本身。 –

+0

@Remy,我如何刪除源列表,因爲它是通過常量引用傳遞的...我無法修改它 –

+0

因此,在這最後,你應該有兩個列表 - 一個列表是兩個列表的連接,第二個列表沒有修改?這在你的問題中並不清楚。如果第二個列表沒有被修改,爲什麼不寫一個簡單的循環,爲傳入的列表中的每個節點調用(this hope to you coded it)'this-> insertNode()'或類似的函數? – PaulMcKenzie

回答

1

您的代碼存在一些問題。

一個問題是,它不清楚你期望從插入函數。

其他要插入的列表在哪裏?我會假設該索引應該意味着otherList的頭部將成爲位置索引處的節點(從零開始計數)。這也是你的代碼是做指數= 0,但對於指數= 1你居然後插入當前元素數1。這可以是固定的改變,同時,即

while (x > 1) 

另一個問題是,在使用指針之前您不檢查nullptr。這一定是固定的。

第三個問題是,你當指數> 0

我不知道,如果你的拷貝構造函數是確定你沒有提供的代碼沒有得到一個副本。

這裏是另一種方法(鑲嵌功能改名爲insert_list_copy_at):

class Node 
{ 
public: 
    Node() : next(nullptr) {}; 

    Node(const Node& other) 
    { 
     next = other.next; 

     // Copy other members 
    }; 

    Node* next; 

    // other members 
}; 

class List 
{ 
public: 
    Node* head; 
    Node* tail; 

    void insert_list_copy_at(const List& otherList, int index); 
    void insert_node_at(Node* node, int index); 
}; 

void List::insert_node_at(Node* node, int index) 
{ 
    if (index == 0) 
    { 
     node->next = head; 
     head=node; 
     if (tail == nullptr) 
     { 
      tail=node; 
     } 
      return; 
    } 

    if (head == nullptr) {/*throw exception - index out of range*/}; 

    Node* t = head; 
    while(index>1) 
    { 
     t = t->next; 
     if (t == nullptr) {/*throw exception - index out of range*/}; 
    } 

    // Insert node after t 
    node->next = t->next; 
    t->next = node; 
    if (tail == t) 
    { 
     tail=node; 
    } 
} 

void List::insert_list_copy_at(const List& otherList, int index) 
{ 
    Node* t = otherList.head; 
    while(t != nullptr) 
    { 
     // Create new node as copy of node in otherList 
     Node* tmp = new Node(*t); 

     // Insert in this list 
     insert_node_at(tmp, index); 

     // Increment index and pointer 
     index++; 
     t = t->next; 
    } 
} 

BTW - 考慮使用的std ::載體,而不是創建自己的列表中。