好吧,所以对于我的家庭作业,我有一个函数可以从文件输入中创建一个链表,就像日历一样,因此它可以从文件中读取日期和标题。我使用的是全局声明的头节点
更易于使用其他功能。
这是我的节点结构:
typedef struct event_t{
char title[20];
event_date_t date;
struct event_t *next;
}event_t;
event_date_t只是日期的简单结构 功能如下:
void insert_events_linked_list(FILE *file, int n){
//printf("LL function started\n"); //self-explanatory test line
event_t last;
head.next = &last;
int i;
//This loop will create a ll of the specified length
for(i=0; i<n; i++){
event_t *last = malloc(sizeof(event_t));
int title_test = fscanf(file, "%20s%*c", last->title);
printf("%s\n", last->title); //test line to make sure names are grabbed properly
//This skips the rest of the event and prints error message if title is too long
if(title_test != 1){
fscanf(file, "%*s %*d %*d");
printf("Error: LL event %d title too long\n", i++);
continue;
}
else{
fscanf(file, "%d %d", &last->date.month, &last->date.day);
last = last->next;
}
}
printf("Loop exited");
}
测试行将打印所有标题,但显示分段错误并在打印“退出循环”之前中止
答案 0 :(得分:0)
这行代码,
event_t *last = malloc(sizeof(event_t));
每次last
循环返回时,都会声明一个全新的for
。将其声明为static
并相应地调整您的代码,这样就不会有任何问题了。
演示
for (i=0;i<5;i++){
int x=6;
x++;
printf("%d ",x);
}
输出
7 7 7 7 7
您应该看到问题了。
答案 1 :(得分:0)
测试行将打印所有标题,但显示分段错误并在打印“退出循环”之前中止
程序中有很多错误。您应该阅读this post。您还应该学习使用调试器。
我怀疑未打印Loop exited
的原因是您没有用换行符终止它,所以printf
正在等待您完成一行或致电fflush
。默认情况下,printf
输出是 line 缓冲的。这就是您应该始终始终使用fprintf(stderr, ...)
的原因之一。 stderr
(默认情况下)是无缓冲的。
关于错误。
last
的变量。这几乎从来不是一个好主意。此语句:
head.next = &last;
将 local 变量的地址分配给 global head
指针。当前函数返回后,该地址将变为无效,这几乎肯定不是您想要的。特别是,head.next
从不指向循环中您malloc
的任何内存(并且泄漏!)。
您的循环看起来像这样:
for (...) {
event_t *last = malloc(sizeof(event_t)); // last->next is uninitialized
...
last = last->next; // leak the memory allocated above
// by overwriting the pointer with garbage
}
那显然也不是你想要的。
这是一种逐步建立链表的方法:
event_t **link = &head.next;
for (...) {
event_t *ev = calloc(...); // Initializes ev->next to NULL.
// Fill the rest of ev ...
// Link it into the list:
*link = ev;
link = &ev->next;
}