再次显示嵌套列表时丢失它们的元素

时间:2019-06-02 14:23:41

标签: c linked-list nested-lists

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

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

int main() {

struct catalog* head = NULL;
sortedInsert(&head, "Kappa");
sortedInsert(&head, "Aaaaaa");
sortedInsert(&head, "Sdafscx");
sortedInsert(&head, "Saxzxc");
sortedInsert(&head, "Asdas");
sortedInsert(&head, "Zzzzzzzz");
sortedInsert(&head, "Country");
sortedBookInsert(&head, "Country", "PKP", 11111, "Germany");
sortedBookInsert(&head, "Country", "Polacy", 11112, "Italy");
sortedBookInsert(&head, "Country", "Autobusy", 11234, "France");
sortedBookInsert(&head, "Country", "Polityka", 14111, "Russia");
printList(head);
printList(head);
return 0;

}

When I print my list for a second time, elements from SortedBookInsert just... are not there. I am very confused.

1 个答案:

答案 0 :(得分:1)

newbook 中缺少返回,必须为

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;

    return newbook;
}

没有返回,行为是不确定的。

请注意,您还会创建2个内存泄漏:

newbook->title = malloc(sizeof(strlen(booktitle)+1));
newbook->country = malloc(sizeof(strlen(country)+1));
newbook->title = booktitle;
newbook->country = country;

,但是由于 sizeof ,您还没有分配正确的长度,必须为

newbook->title = malloc(strlen(booktitle)+1);
newbook->country = malloc(strlen(country)+1);
strcpy(newbook->title, booktitle);
strcpy(newbook->country, country);

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

但坦率地说,我不确定这一点

findcatalog

if(current->name == catalogname)

必须

if(!strcmp(current->name, catalogname))

函数 printList 修改目录temp->firstbook = temp->firstbook->new;,需要替换

   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 $ 

valgrind

下执行
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

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