C 第二次显示嵌套列表的元素时丢失这些元素

C 第二次显示嵌套列表的元素时丢失这些元素,c,linked-list,nested-lists,C,Linked List,Nested Lists,我正在尝试使用嵌套列表创建一个“库”。一切正常,我可以使用排序的add函数添加元素,直到我注意到,如果我连续两次显示列表,第一次一切都会正常,但在第二次显示中,添加到目录中的“book元素”不会显示,就像它们不存在一样 struct book { char *title; int number; char *country; struct book* new; }; struct catalog { char *name; struct cata

我正在尝试使用嵌套列表创建一个“库”。一切正常,我可以使用排序的add函数添加元素,直到我注意到,如果我连续两次显示列表,第一次一切都会正常,但在第二次显示中,添加到目录中的“book元素”不会显示,就像它们不存在一样

struct book
{
    char *title;
    int number;
    char *country;
    struct book* new;
};

struct catalog
{
    char *name;
    struct catalog* next;
    struct book* firstbook;
};

void printList(struct catalog *head)
{
    struct catalog *temp = head;
    while(temp != NULL)
    {
        if(temp->firstbook == NULL)
        {
            printf("%s\n", temp->name);

        }
        while(temp->firstbook != NULL)
        {   printf("%s  ", temp->name);
            printf("%s  ", temp->firstbook->title);
            printf("%d  ", temp->firstbook->number);
            printf("%s\n", temp->firstbook->country);
            temp->firstbook = temp->firstbook->new;
        }
        temp = temp->next;
    }
}

struct book *newbook(char *booktitle, int number, char *country)
{
    struct book* newbook = (struct book*) malloc(sizeof(struct book));
    newbook->title = malloc(sizeof(strlen(booktitle)+1));
    newbook->country = malloc(sizeof(strlen(country)+1));
    newbook->title = booktitle;
    newbook->country = country;
    newbook->number = number;
    newbook->new = NULL;
}

struct catalog *findcatalog(struct catalog** head, char *catalogname)
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        if(current->name == catalogname)
        {
            return current;
        }
        current = current->next;
    }
}

void sortedBookInsert(struct catalog** head, char *catalogname, char *booktitle, int number, char *country)
{
    struct catalog* searched;
    struct book* pom;
    struct book* ksiazka = newbook(booktitle, number, country);
    searched = findcatalog(head, catalogname);
    if(searched->firstbook == NULL || strcmp(searched->firstbook->title, ksiazka->title)>0)
    {
        ksiazka->new =searched->firstbook;
        searched->firstbook = ksiazka;
    }
    else
    { pom = searched->firstbook;
        while(pom->new!= NULL && strcmp(searched->firstbook->title, ksiazka->title)< 0)
        {
            pom = pom->new;
        }
        ksiazka->new = pom->new;
        pom->new = ksiazka;
    }
}

void sortedInsert(struct catalog** head,char *name)
{
    struct catalog* current;
    struct catalog* new_node = newcatalog(name);

    if (*head == NULL || strcmp((*head)->name, new_node->name) > 0)
    {
        new_node->next = *head;
        *head = new_node;
    }
    else
    {
        current = *head;
        while (current->next!=NULL && strcmp(current->next->name, new_node->name) < 0)
        {
            current = current->next;
        }
        new_node->next = current->next;
        current->next = new_node;
    }
}
}

newbook中缺少返回,必须

如果没有返回,则行为是未定义的

注意:您还通过以下操作创建了2个内存泄漏:

但由于sizeof的大小,您也没有分配正确的长度,必须

在findcatalog中也没有返回,如果找不到目录,则必须返回

struct catalog *findcatalog(struct catalog** head, char *catalogname)
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        if(current->name == catalogname)
        {
            return current;
        }
        current = current->next;
    }
    return NULL;
}
如果没有返回,则行为是未定义的

在sortedBookInsert中,您可能需要在执行
searched->firstbook
之前检查searched是否为NULL,例如:

void sortedBookInsert(struct catalog** head, char *catalogname, char *booktitle, int number, char *country)
{
    struct catalog* searched;
    struct book* pom;
    struct book* ksiazka = newbook(booktitle, number, country);
    searched = findcatalog(head, catalogname);
    if (searched == NULL)
      return;
    if(searched->firstbook == NULL || strcmp(searched->firstbook->title, ksiazka->title)>0)
    {
        ksiazka->new =searched->firstbook;
        searched->firstbook = ksiazka;
    }
    else
    { pom = searched->firstbook;
        while(pom->new!= NULL && strcmp(searched->firstbook->title, ksiazka->title)< 0)
        {
            pom = pom->new;
        }
        ksiazka->new = pom->new;
        pom->new = ksiazka;
    }
}
struct book* firstbook = temp->firstbook;

    while(firstbook != NULL)
    {   printf("%s  ", temp->name);
        printf("%s  ", firstbook->title);
        printf("%d  ", firstbook->number);
        printf("%s\n", firstbook->country);
        firstbook = firstbook->new;
    }
一定是

if(!strcmp(current->name, catalogname))
函数printList修改目录做
temp->firstbook=temp->firstbook->new,您需要替换

例如:

void sortedBookInsert(struct catalog** head, char *catalogname, char *booktitle, int number, char *country)
{
    struct catalog* searched;
    struct book* pom;
    struct book* ksiazka = newbook(booktitle, number, country);
    searched = findcatalog(head, catalogname);
    if (searched == NULL)
      return;
    if(searched->firstbook == NULL || strcmp(searched->firstbook->title, ksiazka->title)>0)
    {
        ksiazka->new =searched->firstbook;
        searched->firstbook = ksiazka;
    }
    else
    { pom = searched->firstbook;
        while(pom->new!= NULL && strcmp(searched->firstbook->title, ksiazka->title)< 0)
        {
            pom = pom->new;
        }
        ksiazka->new = pom->new;
        pom->new = ksiazka;
    }
}
struct book* firstbook = temp->firstbook;

    while(firstbook != NULL)
    {   printf("%s  ", temp->name);
        printf("%s  ", firstbook->title);
        printf("%d  ", firstbook->number);
        printf("%s\n", firstbook->country);
        firstbook = firstbook->new;
    }
如果我做了所有这些修改并使用此定义:

struct catalog* newcatalog(char *name)
{
  struct catalog* r = malloc(sizeof(struct catalog));

  r->name = malloc(strlen(name)+1);
  strcpy(r->name, name);
  r->next = NULL;
  r->firstbook = NULL;

  return r;
}
汇编和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wall -Wextra l.c
pi@raspberrypi:/tmp $ ./a.out
one
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
two
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
pi@raspberrypi:/tmp $ 
瓦尔格林死刑



请注意,在代码中,您为名称/书名/国家/地区提供了文字字符串,因此它们永远不会消失/更改,因此复制它们是无用的,但在“真正”的情况下,您不会重复使用相同的数组或字符,从文件中获取它们或在stdin等上读取它们,因此,我建议您按照我的建议复制它们

这会得出结论,警告没有打开,否则编译器会抱怨。@PaulOgilvie绝对不会,或者OP没有考虑它们谢谢您的回答。我没有使用Valgrind(事实上,我从未使用过它,我只是开始编程),我的编译器也没有给我任何警告。然而,我的主要问题是,为什么在链表的第二次打印中没有打印图书元素,以及如何修复它,所以它们被打印。我认为它们被正确地插入到某个目录中,但它们只是消失了,我不知道为什么。你能帮我解决这个问题吗?@Tytanuser我之前没有看到一个错误,因为意外的大小of,我编辑了我的答案,请重新阅读,现在执行是相同的两倍。使用valgrind时,我没有看到这些错误,因为我使用strdup替换了malloc/strcpytests@bruno所以现在我的sortedBookInsert函数似乎有一个更大的问题,因为现在它根本不向目录中添加书籍,但我不知道为什么,它以前工作过,主要是缺少退货,看看我的答案,允许有一个(先验)有效的版本/执行
if(!strcmp(current->name, catalogname))
   while(temp->firstbook != NULL)
   {   printf("%s  ", temp->name);
       printf("%s  ", temp->firstbook->title);
       printf("%d  ", temp->firstbook->number);
       printf("%s\n", temp->firstbook->country);
       temp->firstbook = temp->firstbook->new;
   }
struct book* firstbook = temp->firstbook;

    while(firstbook != NULL)
    {   printf("%s  ", temp->name);
        printf("%s  ", firstbook->title);
        printf("%d  ", firstbook->number);
        printf("%s\n", firstbook->country);
        firstbook = firstbook->new;
    }
struct catalog* newcatalog(char *name)
{
  struct catalog* r = malloc(sizeof(struct catalog));

  r->name = malloc(strlen(name)+1);
  strcpy(r->name, name);
  r->next = NULL;
  r->firstbook = NULL;

  return r;
}
pi@raspberrypi:/tmp $ gcc -g -pedantic -Wall -Wextra l.c
pi@raspberrypi:/tmp $ ./a.out
one
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
two
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
pi@raspberrypi:/tmp $ 
pi@raspberrypi:/tmp $ valgrind ./a.out
==7575== Memcheck, a memory error detector
==7575== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7575== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==7575== Command: ./a.out
==7575== 
one
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
two
Aaaaaa
Asdas
Country  Autobusy  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Polityka  14111  Russia
Kappa
Saxzxc
Sdafscx
Zzzzzzzz
==7575== 
==7575== HEAP SUMMARY:
==7575==     in use at exit: 148 bytes in 11 blocks
==7575==   total heap usage: 12 allocs, 1 frees, 1,172 bytes allocated
==7575== 
==7575== LEAK SUMMARY:
==7575==    definitely lost: 12 bytes in 1 blocks
==7575==    indirectly lost: 136 bytes in 10 blocks
==7575==      possibly lost: 0 bytes in 0 blocks
==7575==    still reachable: 0 bytes in 0 blocks
==7575==         suppressed: 0 bytes in 0 blocks
==7575== Rerun with --leak-check=full to see details of leaked memory
==7575== 
==7575== For counts of detected and suppressed errors, rerun with: -v
==7575== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from