#c #data-structures #linked-list
#c #структуры данных #связанный список
Вопрос:
Я пытаюсь создать связанный список на C, где он считывается из входного файла и либо добавляет, либо удаляет узлы. Я получаю ошибку AddressSanitizer: DEADLYSIGNAL (на фото), которая, как я думаю, связана с разыменованием нулевого указателя в моей функции insert node, но я не могу найти, где я это делаю. Если я ошибаюсь в том, что означает эта ошибка, или вы видите, где я ошибаюсь, это было бы огромной помощью. Большое спасибо!!
»’
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *next;
} Node;
void printList(Node *head){
Node *temp = head->next;
int count;
while(temp != NULL){
temp = temp->next;
count ;
}
printf("%dn", count);
temp = head->next;
while(temp != NULL){
printf("%dt", temp->data);
temp = temp->next;
}
}
Node *makeNode(int value){
Node *newNode = malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
void insertNode(Node *head, Node *newNode){
Node *temp ,*prev;
temp = head;
while(temp != NULL amp;amp; temp->data <= newNode->data) {
prev = temp;
temp = temp->next;
}
newNode->next = temp;
prev->next = newNode;
}
void deleteNode(Node *head, int deleteNum){
if(head->next != NULL){
if(head->next->data == deleteNum){
head->next = head->next->next;
free(head->next);
}
else{
//printf("hello");
Node *temp ,*prev;
temp = head;
while(temp != NULL amp;amp; temp->data != deleteNum) {
prev = temp;
temp = temp->next;
}
if(temp != NULL){
prev->next = temp->next;
//free(temp);
}
}
}
}
int main(int argc, char* argv[])
{
Node* head = malloc(sizeof(Node));
Node *temp;
char* filename = argv[1];
if(fopen(filename, "r") == NULL){
printf("error");
}
else{
FILE* fp = fopen(filename, "r");
char mode;
int tempData;
while (fscanf(fp, "%ct%dn", amp;mode, amp;tempData ) == 2) {
//printf("%cn", mode);
if(mode == 'i'){
//printf("%cn", 'i');
Node *insert = makeNode(tempData);
insertNode(head, insert);
}
else if(mode == 'd'){
//printf("%cn", 'd');
//printList(head);
deleteNode(head, tempData);
//printList(head);
}
}
printList(head);
}
}
Комментарии:
1. Можете ли вы предоставить входные данные, которые вызывают сбой?
Ответ №1:
Вы никогда не инициализируете узел, который head
указывает на in main
, поэтому, когда вы передаете его insertNode
, значение head->next
может быть мусором; в частности, оно может быть не нулевым. В этом случае while
цикл будет выполняться как минимум две итерации, устанавливая temp
указатель на мусор head->next
, и доступ temp->data
к условию while
разыменования этого указателя на мусор. Отсюда и сбой.
Вы, вероятно, хотите head->next = NULL;
где-то main
после malloc
, но перед insertNode
. Или, что еще лучше, используйте существующую makeNode
функцию для выделения head
.
Существует еще одна ошибка, заключающаяся в том, что вы также никогда не инициализируете head->data
, с которой сравнивается newNode->data
. Если мусор в head->data
больше, чем newNode->data
, insertNode
попытается вставить его в список до head
, что не сработает и просто приведет к потере узла. Кроме prev
того, будет использоваться неинициализированный, что, вероятно, также приведет к сбою. Вы могли бы обойти это, инициализировав head->data
to INT_MIN
, но было бы лучше исправить логику insertNode
, чтобы она никогда не сравнивалась с head->data
в первую очередь. deleteNode
имеет аналогичную проблему.
Еще одна бонусная ошибка: count
неинициализируется printList
.
Вы могли бы обнаружить последние ошибки, скомпилировав с -Wall -O
; затем gcc обнаружит и предупредит о неинициализированных переменных. valgrind
также обнаружена printList
ошибка для меня.