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;
        }
    }