C 尝试打印链接列表中的节点时,该节点似乎为空
所以,事情是这样的。我有一个程序,它将不同的作者存储在一个链表中,每个作者都有自己的记录,每个记录都保存着自己的文本,并组织在一个链表中。数据从文件中读取。代码如下:C 尝试打印链接列表中的节点时,该节点似乎为空,c,list,linked-list,C,List,Linked List,所以,事情是这样的。我有一个程序,它将不同的作者存储在一个链表中,每个作者都有自己的记录,每个记录都保存着自己的文本,并组织在一个链表中。数据从文件中读取。代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> struct AuthorRecord { char textTitle[100]; int Number
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct AuthorRecord
{
char textTitle[100];
int NumberOfWords;
long Download;
struct AuthorRecord *next;
};
typedef struct AuthorRecord *AuthorRecordType;
typedef struct
{
char firstName[30];
char lastName[30];
int idNumber;
int textNum;
AuthorRecordType text;
} AuthorType;
struct MemberNodeStruct
{
AuthorType *anAuthor;
struct MemberNodeStruct *next;
};
typedef struct MemberNodeStruct *MemberNodeType;
FILE* input;
FILE* output;
MemberNodeType head;
MemberNodeType member;
int main (void)
{
int authorNum, textNum, i, j;
member = malloc(sizeof(struct MemberNodeStruct));
head = member;
member->next = NULL;
input = fopen("input.txt", "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
fscanf(input, "%d", &authorNum);
for (i = 0; i < authorNum; i++)
{
member->anAuthor = malloc(sizeof(AuthorType));
textNum = 0;
if(fscanf(input, "%s %s %d", member->anAuthor->lastName, member->anAuthor->firstName, &member->anAuthor->idNumber) != EOF)
{
fscanf(input, "%d", &member->anAuthor->textNum);
for (j = 0; j < member->anAuthor->textNum; j++)
{
member->anAuthor->text = malloc(sizeof(struct AuthorRecord));
fscanf(input, " %[^\n]", member->anAuthor->text->textTitle);
fscanf(input, "%ld", &member->anAuthor->text->Download);
member->anAuthor->text = member->anAuthor->text->next;
}
member->next = malloc(sizeof(MemberNodeType));
member = member->next;
}
else
member->next = NULL;
}
member = head;
while(true)
{
if (member->next == NULL)
break;
for (i = 0; i < authorNum; i++)
{
printf("%s %s %d\n", member->anAuthor->lastName, member->anAuthor->firstName, member->anAuthor->idNumber);
for (j = 0; j < member->anAuthor->textNum; j++)
{
printf("%s\n", member->anAuthor->text->textTitle);
printf("%ld\n", member->anAuthor->text->Download);
member->anAuthor->text = member->anAuthor->text->next;
}
member = member->next;
}
}
}
#包括
#包括
#包括
#包括
结构AuthorRecord
{
字符文本标题[100];
整数字;
长下载;
结构AuthorRecord*下一步;
};
typedef结构AuthorRecord*AuthorRecordType;
类型定义结构
{
charfirstname[30];
char lastName[30];
国际电话号码;
int textNum;
AuthorRecordType文本;
}作者类型;
结构MemberNodeStruct
{
AuthorType*作者;
结构成员nodestruct*next;
};
类型定义结构MemberNodeStruct*MemberNodeType;
文件*输入;
文件*输出;
MemberNodeType头;
MemberNodeType成员;
内部主(空)
{
int authorNum,textNum,i,j;
成员=malloc(sizeof(struct MemberNodeStruct));
头=成员;
成员->下一步=空;
输入=fopen(“input.txt”,“r”);
如果(输入==NULL)
{
printf(“无法打开文件。\n”);
返回1;
}
fscanf(输入、%d、&authorNum);
对于(i=0;i作者=malloc(sizeof(AuthorType));
textNum=0;
如果(fscanf(输入,“%s%s%d”,成员->作者->姓氏,成员->作者->姓氏,&成员->作者->身份证号码)!=EOF)
{
fscanf(输入,“%d”,&member->anaauthor->textNum);
对于(j=0;janaauthor->textNum;j++)
{
成员->作者->文本=malloc(sizeof(struct AuthorRecord));
fscanf(输入“%[^\n]”,成员->作者->文本->文本标题);
fscanf(输入,“%ld”,&成员->作者->文本->下载);
成员->作者->文本=成员->作者->文本->下一步;
}
member->next=malloc(sizeof(MemberNodeType));
成员=成员->下一步;
}
其他的
成员->下一步=空;
}
成员=负责人;
while(true)
{
如果(成员->下一步==NULL)
打破
对于(i=0;i作者->姓氏,成员->作者->名字,成员->作者->ID号);
对于(j=0;janaauthor->textNum;j++)
{
printf(“%s\n”,成员->作者->文本->文本标题);
printf(“%ld\n”,成员->作者->文本->下载);
成员->作者->文本=成员->作者->文本->下一步;
}
成员=成员->下一步;
}
}
}
我已经通过gdb运行了这个程序,一切都很好。但是,当我到达这一行时,printf(“%s\n”,member->anaauthor->text->textitle)代码>我有一个错误。
显然,member->anaauthor->text
字段为空,其地址为0x0。member
和member->anaauthor
上的数据和内存地址正确
这里怎么了 阅读每个作者的文本时,使用autor节点的text
成员作为迭代器
for (j = 0; j < member->anAuthor->textNum; j++)
{
member->anAuthor->text = malloc(sizeof(struct AuthorRecord));
fscanf(input, " %[^\n]", member->anAuthor->text->textTitle);
fscanf(input, "%ld", &member->anAuthor->text->Download);
member->anAuthor->text = member->anAuthor->text->next;
}
for(j=0;janaauthor->textNum;j++)
{
成员->作者->文本=malloc(sizeof(struct AuthorRecord));
fscanf(输入“%[^\n]”,成员->作者->文本->文本标题);
fscanf(输入,“%ld”,&成员->作者->文本->下载);
成员->作者->文本=成员->作者->文本->下一步;
}
整个街区的逻辑是错误的text->next
从来没有有意义的值,甚至NULL
。文本没有链接,它们只是不相关的数据块,一旦循环被遍历就无法访问。特别是,您必须首先分配,然后将上一个链接的next
指针设置为指向该内存
文本列表的文本
指针应该类似于成员列表中的头
,并且只能分配一次。(即,在使用NULL
初始化之后。)
也就是说,在您的代码中有多种:
- 这些建筑的名字很恐怖。我知道这是一项任务,您的任务是以结构为起点,但为什么文本节点称为
AuthorRecord
,而它们显然不同于autotype
- 正如已经指出的,为结构定义指针类型不会增加任何内容;它只会混淆,特别是如果类型命名为
AuthorRecordType
,而不是authortr
或pautor
。在C语言中,星号表示指针类型;很难比这更有表现力。(此外,打字更容易。)
- 跟踪具有额外成员的列表中的条目数可能很有用,但列表的遍历应始终与列表结构本身(即
下一个指针)一起进行,以避免可能的不一致
- 向列表中添加元素时,请在需要内存时调用
malloc
,不要提前调用。如果在读取第一个元素之前对其进行malloc,然后将其设置为NULL
,因为结果表明您根本不需要它,则会造成内存泄漏
- 完成后,每个
malloc
都需要一个free
。(我知道你的代码目前还不完整,只是说说而已。)
- 您的整个
scanf
序列需要进行错误检查。如果输入不正确,很容易进入无限循环。(旁注:在这里发布一小段示例输入也很有帮助,可以帮助我们找到错误。)
- 考虑使用小函数来创建每个类型,清理它们并将它们添加到列表中;不要将所有内容都放入
main
。把阅读和创造结构分开也是一个好主意
- 使用长序列的成员引用,如下所示:
member->a
There are several items to note in your code,
such as the definition of struct { fields } name; is depreciated
and should not be used in new code.
Rather use: struct name { fields };
which does require using 'struct' wherever the structure name is referenced.
There are several logic errors in the code that are causing it to fail,
such as not initializing the pointers to malloc'd areas to null.
Note: all the malloc'd areas need to be free'd at each exit point,
without back links, the free processing will be time consuming
Suggest adding a back link to each malloc'd area to simplify that operation
Also, the struct MemberNode is not needed
because a linked list of the struct AuthorType would contain all the relevant data.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct AuthorRecord
{
char textTitle[100];
int NumberOfWords;
long Download;
struct AuthorRecord *next;
};
struct AuthorType
{
char firstName[30];
char lastName[30];
int idNumber;
int textNum;
struct AuthorRecord text;
};
struct MemberNode
{
struct AuthorType *anAuthor;
struct MemberNode *next;
};
FILE* input;
struct MemberNode *head = NULL; // head of linked list
struct MemberNode *member = NULL; // ptr to current item in linked list
int main (void)
{
int authorNum, textNum, i, j;
input = fopen("input.txt", "r");
if (NULL == input)
{
perror("fopen(input.txt) %s", strerror(errno) );
return (errno);
}
// read number of authors
fscanf(input, "%d", &authorNum);
// for each author
for (i = 0; i < authorNum; i++)
{
// one of member struct per author
if( NULL == member )
{ // first time
member = (struct MemberNode*)malloc(sizeof(struct MemberNode));
head = member;
member->next = NULL; // initialize
}
else
{ // not first time
// link to new member node
member->next = (struct MemberNode*)malloc(sizeof(struct MemberNode);
if( NULL == member->next )
{
perror( "malloc(MemberNode) %s", strerror( errno ) );
return(errno);
}
//memset( member->next, 0x00, sizeof(struct MemberNode) );
member = member->next; // step to new member node
member->anAuthor = NULL; // initialize ptr to author info list
member->next = NULL; // initialize
}
// set secondary linked list member(author) & point to it
member->anAuthor = (struct AuthorType*)malloc(sizeof(struct AuthorType));
if( NULL == member->anAuthor )
{
perror( "malloc(AuthorType) %s", strerror( errno ) );
return(errno);
}
//memset( member->anAuthor, 0x00, sizeof(struct AuthorType) );
member->anAuthor->next = NULL; // initialize
member->anAuthor->text = NULL; // initialize
// read a line of author info
if(fscanf(input, "%s %s %d",
member->anAuthor->lastName,
member->anAuthor->firstName,
&(member->anAuthor->idNumber) ) != EOF)
{ // then, successful read of author info
// read number of author titles
fscanf(input, "%d", &(member->anAuthor->textNum));
// for each author title
for (j = 0; j < member->anAuthor->textNum; j++)
{
member->anAuthor->text =
(struct AuthorRecord*)malloc(sizeof(struct AuthorRecord));
if( NULL == member->anAuthor->text )
{
perror( "malloc(AuthorRecord) %s", strerror( errno ) );
return(errno);
}
//memset( member->anAuthor->text, 0x00, sizeof(struct AuthorRecord) );
// step to new author/text record
member->anAuthor->text = member->anAuthor->text->next;
member->anAuthor->text->next = NULL; // initialize
// read one title and how many times that title has been downloaded
fscanf(input, " %[^\n]", member->anAuthor->text->textTitle );
fscanf(input, "%ld", &(member->anAuthor->text->Download) );
}
}
}
// recall beginning of linked list
member = head;
//for each entry in linked list
while(NULL != member) // allow for empty list or end of list
{
if( NULL != member->anAuthor )
{
printf("%s %s %d\n",
member->anAuthor->lastName,
member->anAuthor->firstName,
member->anAuthor->idNumber);
// for each author/text
while( NULL != member->anAuthor->text->next )
{
printf("%s\n%ld\n",
member->anAuthor->text->textTitle,
member->anAuthor->text->Download);
// step to next author text/title
member->anAuthor->text = member->anAuthor->text->next;
}
}
// step to next member (I.E next author)
member = member->next;
}
}