Ошибка шины: 10 в C++ при реализации односвязного списка

Я пытаюсь реализовать односвязный список самостоятельно на C++ с нуля, так далеко продвинувшись с моим первым методом append():

#include <iostream>
using namespace std;

struct ListNode{
    int key_value;
    ListNode *next;
};

class List{ 
    public:
        List();
        void append(int key);

    private:
        ListNode *head;
        ListNode *tail;
};

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

void List::append(int key){
    ListNode *newnode;
    newnode->key_value = key;
    newnode->next = NULL;

    if(head == NULL){
        head = newnode;
        tail = head;
    }
    else{
        tail->next = newnode;
        tail = newnode;
    }
    return;
}

int main(){
    try{ 
        List l1;
        l1.append(1);
        //l1.append(2);
        //l1.append(3);
        //l1.append(5);
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        return -1;
    } 
}

Он компилируется без каких-либо предупреждений или ошибок, но во время выполнения я получаю только сообщение Bus error: 10, Кажется, что-то не так с тем, как я инициализирую и использую переменные и указатели ListNode, любые идеи будут оценены.

1 ответ

Решение

В этой строке:

ListNode *newnode;

вы создаете неинициализированную переменную указателя на ListNode и тогда вы разыменовываете это. Любой доступ к неинициализированной переменной ведет к UB, но с указателями вы, скорее всего, сразу же получите ошибку шины. Итак, выделите память:

ListNode *newnode = new ListNode;

Примечание: вместо инициализации элементов данных:

newnode->key_value = key;
newnode->next = NULL;

Вы должны предоставить правильный конструктор для ListNode:

struct ListNode {
    int key_value;
    ListNode *next;

    ListNode( int v ) : 
        key_value( v ),
        next( nullptr )
    {
    }
};

затем просто создайте его:

  ListNode *newnode = new ListNode( key );

и следующие 2 строки могут быть опущены. Это сделает ваш код чище и предотвратит создание ListNode экземпляр с неинициализированными данными.

Примечание N2: как ваш класс List имеет необработанный указатель и право собственности на данные, которым следует следовать правилу трех и создавать или отключать копирование ctor, оператора присваивания и dtor.

Другие вопросы по тегам