Я пытаюсь реализовать односвязный список самостоятельно на 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 переменные и указатели, любые идеи будут оценены.
В этой строке:
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.
Других решений пока нет …