gpt4 book ai didi

c - 单链表

转载 作者:太空宇宙 更新时间:2023-11-04 00:11:32 26 4
gpt4 key购买 nike

我创建了一个单链表。一切正常。

我只想知道我是否在我的代码中做了任何有潜在危险的事情。我关心的代码片段是我的推送、弹出和清理。部分代码仅用于用户交互,因此并不重要(无论如何我都发布了它,以便更清楚地了解我在做什么)。只是链表应用。

非常感谢任何建议,因为这是我的第一次尝试。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct product_data product_data_t;
struct product_data
{
int product_code;
char product_name[128];
int product_cost;
product_data_t *next;
};

static product_data_t *head = NULL;
static product_data_t *tail = NULL;
static product_data_t *new_product = NULL;

// Push a product on to the list.
void push(int code, char name[], int cost);
// Pop (delete) a product from the list.
void pop(int code);
// Display all product in the list.
void display_list();
// Delete all memory allocated on the list
void clean_up();
// Display menu
void menu();

int main(void)
{
menu();

getchar();

return 0;
}

void push(int code, char name[], int cost)
{
// Allocate memory for the new product
new_product = calloc(1, sizeof(product_data_t));
if(!new_product)
{
fprintf(stderr, "Cannot allocated memory");
exit(1);
}

/* Populate new products elements fields */
new_product->product_code = code;
strncpy(new_product->product_name, name, sizeof(new_product->product_name));
new_product->product_cost = cost;
new_product->next = NULL;

// Set the head and tail of the linked list
if(head == NULL)
{
// First and only product
head = new_product;
}
else
{
tail->next = new_product;
}

tail = new_product;
}

// Find the product by code and delete
void pop(int code)
{
product_data_t *product = head;
product_data_t *temp = NULL;
product_data_t *previous = head;
int found = 0; // 0 - Not Found, 1 - Found

if(!head)
{
puts("The list is empty");
return;
}

while(product)
{
if(product->product_code == code)
{
found = 1; // Found
// Check if this is in the first node - deleting from head
if(head->product_code == code)
{
temp = head;
head = head->next;
free(temp);

// Finished Deleting product
return;
}

// Check if this is the end node - deleting from the tail
if(tail->product_code == code)
{
temp = tail;
tail = previous;
free(temp);

// Finished deleting product
return;
}

// delete from list if not a head or tail
temp = product;
previous->next = product->next;
free(temp);

// Finished deleting product
return;
}
// Get the address of the previous pointer.
previous = product;
product = product->next;
}

if(!found)
{
printf("code [ %d ] was not found\n", code);
}

// Set all to null after finished with them
product = NULL;
temp = NULL;
previous = NULL;
}

// Traverse the linked list
void display_list()
{
// Start at the beginning
product_data_t *product = head;

while(product)
{
printf("===================================\n");
printf("Product code: \t\t%d\n", product->product_code);
printf("Product name: \t\t%s\n", product->product_name);
printf("product cost (USD): \t%d\n", product->product_cost);
printf("===================================\n\n");

// Point to the next product
product = product->next;
}
// Finished set to null
product = NULL;
}

// Release all resources
void clean_up()
{
product_data_t *temp = NULL;

while(head)
{
temp = head;
head = head->next;
free(temp);
}
head = NULL;
temp = NULL;

// End program - goodbye
exit(0);
}

void menu()
{
int choice = 0, code = 0, cost = 0;
char name[128] = {0};

do
{
fflush(stdin); // Flush the input buffer

puts("========= Welecome to linked list ===============");
puts("[1] Add new product to the list");
puts("[2] Delete a product from the list");
puts("[3] Display all products");
puts("[4] Exit and clean up");
printf("Enter your choice: ");
scanf("%d", &choice);

switch(choice)
{
case 1:
printf("Enter product code: ");
scanf("%d", &code);
printf("Enter cost: ");
scanf("%d", &cost);
printf("Enter name: ");
scanf("%s", name);
push(code, name, cost);
break;

case 2:
printf("Enter product code: ");
scanf("%d", &code);
pop(code);
break;

case 3:
display_list();
break;

case 4:
clean_up();
break;

default:
puts("Incorrect choice");
break;
}
}while(choice != 4);
}

最佳答案

来自 pop()

            if(head->product_code == code)
{
temp = head;
head = head->next;
free(temp);

// Finished Deleting product
return;
}

在只有一项的情况下,'head' 和 'tail' 将指向同一个节点。但是,如果弹出这一项,“head”将被调整,但“tail”仍将指向空闲的节点。这将留下一个错误的指针,这可能会导致您的计算机爆炸。

附录:类似地,如果您弹出被推送的最后一个节点,“new_product”将悬空,而 clean_up() 也会使“tail”指针悬空。即使提供的代码示例在它们被释放后永远不会取消引用它们,C 代码中的悬空指针也应始终被视为“潜在危险”。

关于c - 单链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/973654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com