Hello,
I have created a single linked list. Everything works fine.
I just want to know if I have done anything potentially dangerous in my code. The code snippets I am concerned about is my push, pop, and clean-up. The parts of the code is just for user interaction so not really important (I posted anyway so that it was more clear in what I was doing). Just the linked list application.
Many thanks for any suggestions, as this is my fist attempt.
#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);
}