我正在尝试使用嵌套列表构建一个"库"。一切正常,我可以使用我的排序添加函数添加元素,直到我注意到,如果我连续显示两次列表,第一次一切都会很好,但在第二个中,添加到目录中的"书籍元素"没有显示,就像它们不存在一样。
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("%sn", temp->name);
}
while(temp->firstbook != NULL)
{ printf("%s ", temp->name);
printf("%s ", temp->firstbook->title);
printf("%d ", temp->firstbook->number);
printf("%sn", 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.
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;
但你也没有分配正确的长度,因为大小,必须是
newbook->title = malloc(strlen(booktitle)+1);
newbook->country = malloc(strlen(country)+1);
strcpy(newbook->title, booktitle);
strcpy(newbook->country, country);
在查找目录中,如果找不到目录,也没有返回,必须
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中可能需要检查搜索到的是否不是NULL,然后再做searched->firstbook
,例如:
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;
}
}
但坦率地说,我不确定
在查找目录中
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("%sn", 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("%sn", 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
请注意,在您的代码中,您为名称/书名/国家/地区提供文字字符串,因此它们永远不会消失/更改,因此复制它们是没有用的,但是在"真实"情况下,情况并非如此,您重复使用相同的数组或字符从文件中获取它们或在 stdin 等上读取它们,所以我建议您按照我的建议复制它们