簡體   English   中英

鏈表代碼中的分段錯誤,刪除部分

[英]Segmentation fault in Linked List code, deletion part

我正在嘗試對鏈表中的插入和刪除進行編碼。 這是我在單鏈表中基本插入和刪除節點的代碼。 代碼沒有錯誤,但是終端上的output顯示segmentation fault。 有人可以解釋為什么我會遇到分段錯誤嗎? 我做了什么改變來消除故障。 我相信分段錯誤在刪除部分。 請幫忙。

// class is a type of user defined datatype
class Node {
    public:
    int data;
    Node* next;

    //constructor
    Node(int data) {
        this -> data = data;
        this -> next = NULL;
    }

    // destructor
    ~Node() {
        int value = this -> data;
        //memory free krr rhe hain
        if(this -> next != NULL){
            delete next;
            this -> next = NULL;
        }
        cout << "memory is free for node with data" << value << endl;
    }

};

void insertAtHead(Node* &head, int data) {

    // creating new node called temp of type Node 
    Node* temp = new Node(data);
    temp -> next = head;
    head = temp;
}

void insertAtTail(Node* &head, Node* &tail, int data) {
    // //New node create
    // Node* temp = new Node(data);
    // tail -> next = temp;
    // tail = temp;

    Node* temp = new Node(data);
    if (head == nullptr) { // If this is the first node of the list
        head = temp;
    } else { // Only when there is already a tail node
        tail -> next = temp;
    }
    tail = temp;
}

void insertAtPosition(Node* &tail, Node* &head, int position, int data) {

    // Insert at starting
    if(position == 1) {
        insertAtHead(head, data);
        return;
    }

    // Code for inserting in middle
    Node* temp = head;
    int cnt = 1;

    while(cnt < position-1) {
        temp = temp -> next;
        cnt++;
    }

    // Creating a node for data
    Node* nodeToInsert = new Node(data);
    nodeToInsert -> next = temp -> next;
    temp -> next = nodeToInsert;

    // Inserting at last position (tail) 
    if(temp -> next == NULL) {
        insertAtTail(head,tail, data);
        return;
    }
}

void deleteNode(int position, Node* &head) {
    
    //deleting first or starting node
    if(position == 1) {
        Node* temp = head;
        head = head -> next;
        //memory free start node
        temp -> next = NULL;
        delete temp;

    } else {
        // deleting any middle node
        Node* curr = head;
        Node* prev = NULL;

        int cnt = 1;
        while(cnt <= position) {
            prev = curr;
            curr = curr -> next;
            cnt++;
        }

        prev -> next = curr -> next;
        curr -> next = NULL;
        delete curr;
    }
}

void print(Node* &head) {

    Node* temp = head;
    while(temp != NULL) {
        cout << temp -> data << " ";
        temp = temp -> next;
    }
    cout << endl;
}

int main() {

    Node* head = nullptr; // A list has a head
    Node* tail = head; //  a tail.

    insertAtHead(head, 10); // pass the head
    insertAtTail(head, tail, 20);
    insertAtTail(head, tail, 30);
    insertAtHead(head, 5);
    print(head);  // Print the whole list

    cout << "head" << head -> data << endl;
    cout << "tail" << tail -> data << endl;

    deleteNode(1, head);
    print(head);
}

問題不在於刪除 function,因為即使將其注釋掉也會導致分段錯誤。

問題是您正在初始化 tail = head ,它在開始時設置為 nullptr 。 但是,當您 insertAtHead 時,您設置了 head 的值,但將 tail 保留為 nullptr。 添加第一個節點時需要tail = head(當head == nullptr時)。

請參閱下面的工作代碼:

// Online C++ compiler to run C++ program online
#include <iostream>
using namespace std;

// class is a type of user defined datatype
class Node {
    public:
    int data;
    Node* next;

    //constructor
    Node(int data) {
        this -> data = data;
        this -> next = NULL;
    }

    // destructor
    ~Node() {
        int value = this -> data;
        //memory free krr rhe hain
        if(this -> next != NULL){
            delete next;
            this -> next = NULL;
        }
        cout << "memory is free for node with data" << value << endl;
    }

};

void insertAtHead(Node* &head,Node* &tail, int data) {

    // creating new node called temp of type Node 
    Node* temp = new Node(data);
    temp -> next = head;
    
    if (head == nullptr)
        tail = temp; //inializing tail
    
    head = temp;
}

void insertAtTail(Node* &head, Node* &tail, int data) {
    // //New node create
    // Node* temp = new Node(data);
    // tail -> next = temp;
    // tail = temp;

    Node* temp = new Node(data);
    if (head == nullptr) { // If this is the first node of the list
        head = temp;
    } else { // Only when there is already a tail node
        tail -> next = temp;
    }
    tail = temp;
}

void insertAtPosition(Node* &tail, Node* &head, int position, int data) {

    // Insert at starting
    if(position == 1) {
        insertAtHead(head,tail, data);
        return;
    }

    // Code for inserting in middle
    Node* temp = head;
    int cnt = 1;

    while(cnt < position-1) {
        temp = temp -> next;
        cnt++;
    }

    // Creating a node for data
    Node* nodeToInsert = new Node(data);
    nodeToInsert -> next = temp -> next;
    temp -> next = nodeToInsert;

    // Inserting at last position (tail) 
    if(temp -> next == NULL) {
        insertAtTail(head,tail, data);
        return;
    }
}

void deleteNode(int position, Node* &head) {
    
    //deleting first or starting node
    if(position == 1) {
        Node* temp = head;
        head = head -> next;
        //memory free start node
        temp -> next = NULL;
        delete temp;

    } else {
        // deleting any middle node
        Node* curr = head;
        Node* prev = NULL;

        int cnt = 1;
        while(cnt <= position) {
            prev = curr;
            curr = curr -> next;
            cnt++;
        }

        prev -> next = curr -> next;
        curr -> next = NULL;
        delete curr;
    }
}

void print(Node* &head) {

    Node* temp = head;
    while(temp != NULL) {
        cout << temp -> data << " ";
        temp = temp -> next;
    }
    cout << endl;
}

int main() {

    Node* head = nullptr; // A list has a head
    Node* tail = head; //  a tail.

    insertAtHead(head,tail, 10); // pass the head
    insertAtTail(head, tail, 20);
    insertAtTail(head, tail, 30);
    insertAtHead(head,tail, 5);
    print(head);  // Print the whole list

    cout << "head" << head -> data << endl;
    cout << "tail" << tail -> data << endl;

    deleteNode(1, head);
    print(head);
}

段錯誤實際上在 function insertAtTail()中,這是因為,當您處理head是 null 指針的情況時,您沒有處理有head節點但沒有tail節點的情況。 下面的代碼修復了這個問題:

void insertAtTail(Node* &head, Node* &tail, int data) {
    // //New node create
    Node* temp = new Node(data);
    if (head == nullptr) { // If this is the first node of the list
        head = temp;
    } else if (tail == nullptr) { // if there's a head but no tail
        head -> next = temp;
    } else {               // Only when there is already a tail node
        tail -> next = temp;
    }
    tail = temp;
}

如果您查看代碼的這一部分:

int main() 
{
    Node* head = nullptr; // A list has a head
    Node* tail = head; //  a tail.

    insertAtHead(head, 10); // pass the head
    insertAtTail(head, tail, 20);

    return 0;
}

當您將 tail 傳遞給insertAtTail(head, tail, 20); tail是一個 nullptr;

然后在insertAtTail中,您將訪問這個 nullptr:

void insertAtTail(Node* &head, Node* &tail, int data) {
    // //New node create
    // Node* temp = new Node(data);
    // tail -> next = temp;
    // tail = temp;

    Node* temp = new Node(data);
    if (head == nullptr) { 
        head = temp;
    } else { 
        // here you have nullptr access resulting in your segmentation fault
        tail -> next = temp;
    }
    tail = temp;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM