C 链表逻辑错误
我已经为带有头节点的链表编写了一个代码。在删除节点和使用列表中的属性(代码)查找节点时出现逻辑错误。我试过调试,但没有多大帮助。我需要一些帮助来找出错误。谢谢 错误:C 链表逻辑错误,c,debugging,linked-list,valgrind,C,Debugging,Linked List,Valgrind,我已经为带有头节点的链表编写了一个代码。在删除节点和使用列表中的属性(代码)查找节点时出现逻辑错误。我试过调试,但没有多大帮助。我需要一些帮助来找出错误。谢谢 错误: #include <stdlib.h> #include <stdio.h> #include<string.h> struct product { char *title; // Name of the product char code[8]; // Max. 7 cha
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
struct product {
char *title; // Name of the product
char code[8]; // Max. 7 characters of product ID
int stock; // Current stock (number of units)
double price; // Price of a single unit
struct product *next; // pointer to next item in linked list
};
struct product_list {
struct product *head;
// could have other list specific elements, like length of the list, last update time, etc.
};
void init_list (struct product_list *list)
{
list->head = malloc(sizeof(struct product));
}
/* Add product */
/* Parameters:
* start: start of the linked list
* title, code, stock, price: to be copied as created structure content
*
* Returns: pointer to the newly added node in the linked list
*/
struct product *add_product(struct product_list *start, const char *title, const char *code,
int stock, double price) {
struct product_list *newStart = start;
while(newStart->head->next != NULL){
newStart->head = newStart->head->next;
}
if(newStart->head->title == NULL){
newStart->head->title = malloc(strlen(title) + 1);
strcpy(newStart->head->title, title);
strncpy(newStart->head->code, code, 7);
newStart->head->code[7] = 0;
newStart->head->stock = stock;
newStart->head->price = price;
}else{
newStart->head->next = malloc(sizeof(struct product));
newStart->head = newStart->head->next;
newStart->head->title = malloc(strlen(title) + 1);
strcpy(newStart->head->title, title);
strncpy(newStart->head->code, code, 7);
newStart->head->code[7] = 0;
newStart->head->stock = stock;
newStart->head->price = price;
}
return newStart->head;
}
/* Find product */
/* Parameters:
* start: The head node
* code: product code to be found
*
* Returns: Pointer to the first instance of product, or NULL if not found
*/
struct product *find_product(struct product_list *start, const char *code) {
struct product_list *newStart = start;
while(newStart->head != NULL){
if (!strcmp(newStart->head->code, code)) {
return newStart->head;
}else{
newStart->head = newStart->head->next;
}
}
return NULL;
}
/* Remove Product */
/* Parameters:
* start: The head node
* code: value to be removed
*
* Enough to remove first istance, no need to check for dublicates
*
* Returns: The number of removed items (0 or 1)
*/
int remove_product(struct product_list *start, const char *code) {
struct product_list *newStart = start;
if (!strcmp(newStart->head->code, code)) {
free(newStart->head->title);
free(newStart->head);
newStart->head = newStart->head->next;
return 1;
}
while(newStart->head->next !=NULL){
if(!strcmp(newStart->head->next->code, code)){
free(newStart->head->next->title);
newStart->head->next = newStart->head->next->next;
return 1;
}else{
newStart->head = newStart->head->next;
}
}
return 0;
}
/* Delete list */
/* Parameters:
* start: list head
*
* Returns: 1, when list has been deleted
*/
int delete_list(struct product_list *listhead) {
while(listhead->head != NULL){
free(listhead->head->title);
listhead->head = listhead->head->next;
}
return 1;
}
void print_product(struct product *p)
{
printf("%s (%s) -- stock: %d, price: %lf\n",
p->title, p->code,
p->stock, p->price);
}
int main()
{
struct product_list list;
struct product *p;
init_list(&list);
add_product(&list, "test", "1234", 1, 0.50);
add_product(&list, "Product 1", "0000", 0, 10);
add_product(&list, "Long name, isn't it", "1234567890", 10, 100);
add_product(&list, "Product 3", "9999999", 0, 20);
p = find_product(&list, "0000");
if (p)
print_product(p);
else
printf("Not found\n");
int i=remove_product(&list, "0000");
printf("Removed %d items\n", i);
delete_list(&list);
}
==20484== Memcheck, a memory error detector
==20484== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==20484== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==20484== Command: test
==20484==
==20484==
==20484== HEAP SUMMARY:
==20484== in use at exit: 0 bytes in 0 blocks
==20484== total heap usage: 31 allocs, 31 frees, 2,001 bytes allocated
==20484==
==20484== All heap blocks were freed -- no leaks are possible
==20484==
==20484== For counts of detected and suppressed errors, rerun with: -v
==20484== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
#include <stdio.h>
#include <stdlib.h>
#include "products.h"
void print_product(struct product *p)
{
printf("%s (%s) -- stock: %d, price: %lf\n",
p->title, p->code,
p->stock, p->price);
}
int main()
{
struct product_list list;
struct product *p;
init_list(&list);
add_product(&list, "test", "1234", 1, 0.50);
add_product(&list, "Product 1", "0000", 0, 10);
add_product(&list, "Long name, isn't it", "1234567890", 10, 100);
add_product(&list, "Product 3", "9999999", 0, 20);
p = find_product(&list, "0000");
if (p)
print_product(p);
else
printf("Not found\n");
int i=remove_product(&list, "0000");
printf("Removed %d items\n", i);
delete_list(&list);
}
#include <stdlib.h>
#include "products.h"
#include <stdio.h>
#include<string.h>
void init_list (struct product_list *list)
{
list->head = malloc(sizeof(struct product));
}
/* Add product */
/* Parameters:
* start: start of the linked list
* title, code, stock, price: to be copied as created structure content
*
* Returns: pointer to the newly added node in the linked list
*/
struct product *add_product(struct product_list *start, const char *title, const char *code,
int stock, double price) {
while(start->head->next != NULL){
start->head = start->head->next;
}
if(start->head->title == NULL){
start->head->title = malloc(strlen(title) + 1);
strcpy(start->head->title, title);
strncpy(start->head->code, code, 7);
start->head->code[7] = 0;
start->head->stock = stock;
start->head->price = price;
}else{
start->head->next = malloc(sizeof(struct product));
start->head = start->head->next;
start->head->title = malloc(strlen(title) + 1);
strcpy(start->head->title, title);
strncpy(start->head->code, code, 7);
start->head->code[7] = 0;
start->head->stock = stock;
start->head->price = price;
}
return start->head;
}
/* Find product */
/* Parameters:
* start: The head node
* code: product code to be found
*
* Returns: Pointer to the first instance of product, or NULL if not found
*/
struct product *find_product(struct product_list *start, const char *code) {
while(start->head != NULL){
if (!strcmp(start->head->code, code)) {
return start->head;
}else{
start->head = start->head->next;
}
}
return NULL;
}
/* Remove Product */
/* Parameters:
* start: The head node
* code: value to be removed
*
* Enough to remove first istance, no need to check for dublicates
*
* Returns: The number of removed items (0 or 1)
*/
int remove_product(struct product_list *start, const char *code) {
if (!strcmp(start->head->code, code)) {
free(start->head->title);
free(start->head);
start->head = start->head->next;
return 1;
}
while(start->head->next !=NULL){
if(!strcmp(start->head->next->code, code)){
free(start->head->next->title);
start->head->next = start->head->next->next;
return 1;
}else{
start->head = start->head->next;
}
}
return 0;
}
/* Delete list */
/* Parameters:
* start: list head
*
* Returns: 1, when list has been deleted
*/
int delete_list(struct product_list *listhead) {
while(listhead->head != NULL){
free(listhead->head->title);
listhead->head = listhead->head->next;
}
return 1;
}
产品.c
#include <stdio.h>
#include <stdlib.h>
#include "products.h"
void print_product(struct product *p)
{
printf("%s (%s) -- stock: %d, price: %lf\n",
p->title, p->code,
p->stock, p->price);
}
int main()
{
struct product_list list;
struct product *p;
init_list(&list);
add_product(&list, "test", "1234", 1, 0.50);
add_product(&list, "Product 1", "0000", 0, 10);
add_product(&list, "Long name, isn't it", "1234567890", 10, 100);
add_product(&list, "Product 3", "9999999", 0, 20);
p = find_product(&list, "0000");
if (p)
print_product(p);
else
printf("Not found\n");
int i=remove_product(&list, "0000");
printf("Removed %d items\n", i);
delete_list(&list);
}
#include <stdlib.h>
#include "products.h"
#include <stdio.h>
#include<string.h>
void init_list (struct product_list *list)
{
list->head = malloc(sizeof(struct product));
}
/* Add product */
/* Parameters:
* start: start of the linked list
* title, code, stock, price: to be copied as created structure content
*
* Returns: pointer to the newly added node in the linked list
*/
struct product *add_product(struct product_list *start, const char *title, const char *code,
int stock, double price) {
while(start->head->next != NULL){
start->head = start->head->next;
}
if(start->head->title == NULL){
start->head->title = malloc(strlen(title) + 1);
strcpy(start->head->title, title);
strncpy(start->head->code, code, 7);
start->head->code[7] = 0;
start->head->stock = stock;
start->head->price = price;
}else{
start->head->next = malloc(sizeof(struct product));
start->head = start->head->next;
start->head->title = malloc(strlen(title) + 1);
strcpy(start->head->title, title);
strncpy(start->head->code, code, 7);
start->head->code[7] = 0;
start->head->stock = stock;
start->head->price = price;
}
return start->head;
}
/* Find product */
/* Parameters:
* start: The head node
* code: product code to be found
*
* Returns: Pointer to the first instance of product, or NULL if not found
*/
struct product *find_product(struct product_list *start, const char *code) {
while(start->head != NULL){
if (!strcmp(start->head->code, code)) {
return start->head;
}else{
start->head = start->head->next;
}
}
return NULL;
}
/* Remove Product */
/* Parameters:
* start: The head node
* code: value to be removed
*
* Enough to remove first istance, no need to check for dublicates
*
* Returns: The number of removed items (0 or 1)
*/
int remove_product(struct product_list *start, const char *code) {
if (!strcmp(start->head->code, code)) {
free(start->head->title);
free(start->head);
start->head = start->head->next;
return 1;
}
while(start->head->next !=NULL){
if(!strcmp(start->head->next->code, code)){
free(start->head->next->title);
start->head->next = start->head->next->next;
return 1;
}else{
start->head = start->head->next;
}
}
return 0;
}
/* Delete list */
/* Parameters:
* start: list head
*
* Returns: 1, when list has been deleted
*/
int delete_list(struct product_list *listhead) {
while(listhead->head != NULL){
free(listhead->head->title);
listhead->head = listhead->head->next;
}
return 1;
}
您在此处的分配有效地从列表中删除了元素:
start->head = start->head->next;
你要找的可能是一些指针
product* current;
product* nextEl = current->next;
并对其进行迭代:
while (nextEl != null) {
if (!strcmp(nextEl->code, code)) {
product* current->next = nextEl->next;
free (nextEl);
return 1;
}
else {
current = nextEl;
nextEl = nextEl->next;
}
}
return 0;
通常,您应该避免直接使用头指针,使用一些本地指针以防止损坏(如在查找或添加函数中)您在此处的赋值有效地将元素从列表中删除:
start->head = start->head->next;
你要找的可能是一些指针
product* current;
product* nextEl = current->next;
并对其进行迭代:
while (nextEl != null) {
if (!strcmp(nextEl->code, code)) {
product* current->next = nextEl->next;
free (nextEl);
return 1;
}
else {
current = nextEl;
nextEl = nextEl->next;
}
}
return 0;
通常,您应该避免直接使用头指针,使用一些本地指针以防止损坏(如在查找或添加函数中)您的更新代码存在完全相同的问题:
newStart->head = newStart->head->next;
newStart只是开始指针的别名
您应该对列表进行迭代,而不仅仅是将其头部更新为下一个值
例如,列表
A->B->C
将按照如下方式处理您的第一次查找迭代
B->C
由于分配不正确,头部失去了一个元素
它应该是(例如):
您更新的代码存在完全相同的问题:
newStart->head = newStart->head->next;
newStart只是开始指针的别名
您应该对列表进行迭代,而不仅仅是将其头部更新为下一个值
例如,列表
A->B->C
将按照如下方式处理您的第一次查找迭代
B->C
由于分配不正确,头部失去了一个元素
它应该是(例如):
“我尝试过调试,但没有多大帮助。”那么,您发现了什么?当您在产品列表中查找某个项目时,不应该使用列表的头指针进行迭代。使用初始值为head的局部变量。否则,您将销毁该列表。只有在列表前面插入或删除节点时,才应更新头指针。在add_产品中也会出现同样的问题;您正在将start->head指定为指向新条目,因此丢失了列表的实际开始部分。我已将所有内容都放入新代码中,其中包含新head节点的代码。但仍然存在一些逻辑错误。我得到的结果和以前一样。我做错了什么?我做错了什么没有进行任何调试。我尝试过调试,但没有多大帮助。嗯,你发现了什么?当你在产品列表中查找某个项目时,不应该使用列表的头指针进行迭代。使用初始值为head的局部变量。否则,您将销毁该列表。只有在列表前面插入或删除节点时,才应更新头指针。在add_产品中也会出现同样的问题;您正在将start->head指定为指向新条目,因此丢失了列表的实际开始部分。我已将所有内容都放入新代码中,其中包含新head节点的代码。但仍然存在一些逻辑错误。我得到了和以前一样的结果。我做错了什么?我做错了什么不做任何调试。