[英]Linked list shows segmentation fault error
我對 C 和指針很陌生。
以下代碼用於實現一個鏈表,其中每個節點都包含一個記錄數據。
但是,當我編譯並運行該程序時,它顯示錯誤“分段錯誤”,我猜我的代碼中的以下部分會出錯。
head->next = NULL
在列表中的函數中。c
我懷疑由於取消引用 null 指針而發生分段錯誤錯誤,但不知道我的代碼有什么問題。
列表.h
#ifndef LIST_H
#define LIST_H
#include <stddef.h>
#include "record.h"
typedef struct node node;
struct node {
record data;
node *next;
};
typedef node *record_list; /* a record list is represented by its "head"
pointer */
void list_init(record_list *plist);
int list_insert(record_list *plist, const record *prec);
void list_clear(record_list *plist);
void list_print(const record_list *plist);
#endif
io.h
#ifndef IO_H
#define IO_H
#include "record.h"
void print_record(const record *p);
int read_record(record *p);
/* reads a string from stdin */
int get_word(const char prompt[], char word[]);
/* reads an int from stdin */
int get_int(const char prompt[], int *p);
#endif
記錄.h
#ifndef RECORD_H
#define RECORD_H
#define IDSIZE 10
#define NAMESIZE 20
typedef struct {
char last[NAMESIZE];
char first[NAMESIZE];
} name;
typedef struct {
char id[IDSIZE];
name name;
int score;
} record;
#endif
列表.c
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "record.h"
#include "list.h"
#include "io.h"
/* initializes a record list (specified via plist) to an empty list */
void list_init(record_list *plist) {
node *head;
head = *plist;
head = NULL;
head->next = NULL;
printf("%s", "segmentation???\n");
}
/*
* inserts a record (specified via prec) into a record list
*/
int list_insert(record_list *plist, const record *prec) {
node *current, *temp;
printf("%s", "list insert\n");
current = *plist;
while (current->next != NULL) {
current = current->next;
}
temp = (node *)malloc(sizeof(node));
if (temp == NULL) {
fprintf(stderr, "memory allocate failed");
return 0;
}
current->next = temp;
current->next->data = *prec;
current->next->next = NULL;
printf("%s", "list insert done\n");
return 1;
}
/*
* deallocates all dynamic memory associated with a record list (specified
* via plist) & resets the record list to an empty list
*/
void list_clear(record_list *plist) {
printf("%s", "list clear\n");
free((*plist)->next);
plist = NULL;
(*plist)->next = NULL;
}
/* prints all records in a record list (specified via plist) */
void list_print(const record_list *plist) {
node *current;
current = *plist;
printf("%s", "list print\n");
while (current->next != NULL) {
print_record(&(current->data));
current = current->next;
}
}
io.c
#include <stdio.h>
#include <string.h>
#include "record.h"
#include "io.h"
#define LINESIZE 1024
/*
* prints a record (specified via p);
*/
void print_record(const record *p) {
printf("%d %s %s %s\n", p->score, p->name.last, p->name.first, p->id);
}
/*
* reads a record from stadard input & stores it via p;
*/
int read_record(record *p) {
return (
get_word("Enter id: ", p->id)
&& get_word("Enter last name: ", p->name.last)
&& get_word("Enter first name: ", p->name.first)
&& get_int("Enter score: ", &(p->score))
);
}
/* reads a string from stdin */
int get_word(const char prompt[], char word[]){
char line[LINESIZE];
char temp[LINESIZE];
while (1) {
printf("%s", prompt);
if(!fgets(line, LINESIZE, stdin)){
clearerr(stdin);
return 0;
}
if (sscanf(line, "%s", temp) == 1){
strcpy(word, temp);
return 1;
}
}
}
/* reads an int from stdin */
int get_int(const char prompt[], int *p) {
char line[LINESIZE];
while (1) {
printf("%s", prompt);
if (!fgets(line, LINESIZE, stdin)) {
clearerr(stdin);
return 0;
}
if (sscanf(line, "%d", p) == 1) {
return 1;
} else {
printf("%s", "Error: The input is not given in integer.\n");
}
}
}
main.c
#include <stdio.h>
#include "record.h"
#include "list.h"
#include "io.h"
int main(void) {
record_list list;
record r;
printf("address of list: %ld\n", &list);
printf("address of list: %ld\n", &(list->next));
list_init(&list);
while (read_record(&r)) {
printf("%s\n", "read success");
if (!list_insert(&list, &r))
break;
}
list_print(&list);
return 0;
}
如果您的目標是創建一個空列表並且plist
是指向列表頭的指針,則您必須將plist
指向的變量設置為 NULL ,其中*plist = NULL;
,就可以擺脫導致分段錯誤的代碼
好的,我想我發現了下一個錯誤:
current = *plist;
while (current->next != NULL) {
current = current->next;
}
會導致錯誤,因為第一次調用 list_insert 你有 *plist 等於 NULL 因為列表是空的,所以 current->next != NULL 將導致錯誤(current 也等於 NULL)
我建議如下:
printf("%s", "list insert\n");
if (*plist == NULL) {
temp = (node * )malloc(sizeof(node));
if (temp == NULL) {
fprintf(stderr, "memory allocate failed");
return 0;
}
plist = temp;
(*plist) ->data = *prec;
(*plist) ->next = NULL;
return 1;
}
current = *plist;
while (current->next != NULL) {
current = current->next;
}
和代碼的 rest 原樣,我為這種情況添加了一個 if *pilist 等於 NULL,在這種情況下 temp 將指向第一個元素並且必須分配給 plist
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.