When linked list element is created using calloc, how to delete element in the delete function without causing leaking issue?
My delete function can pass the test 1-5 shown in main() but can't pass test 6. The expected result is merely "abc". My result is not just "abc" but also with leaksing issue. Please refer to the attached image.
I think it is because for test 6 the node for 'g' is created explicitly using calloc which needs to be freed using free() method explicitly since the delete function I show here only delete and free memory of the corresponding node from the linkedlist. It doesn't interfere with the element passed. I try to rewrite the code many times but still can't solve the leaking issue.
Any help would be appreciated!
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
struct linkedlistelement_s {
char data;
struct linkedlistelement_s* next;
};
typedef struct linkedlistelement_s LinkedListElement_t;
typedef struct {
LinkedListElement_t* head;
LinkedListElement_t* tail;
} LinkedList_t;
void addElement(LinkedList_t* list, char data);
LinkedListElement_t* findElement(LinkedList_t* list, char data);
void deleteElement(LinkedList_t* list, LinkedListElement_t* element);
int main()
{
/* MAKE SURE TO CHECK THE LEAK USING BELOW COMMAND LINE IN LERMINAL
cc -Wall -g -Werror filename.c -lmcheck
valgrind ./filename.out */
//TEST 1 - expected: ac
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// addElement(&alist, 'b');
// addElement(&alist, 'c');
// element = findElement(&alist, 'b');
// deleteElement(&alist, element);
// for (LinkedListElement_t* elem=alist.head; elem != NULL; elem = elem->next) {
// printf("%c", elem->data);
// }
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
// //TEST 2 - expected: correct
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// element = findElement(&alist, 'a');
// deleteElement(&alist, element);
// printf("%s", (alist.head == NULL && alist.tail == NULL) ? "Correct" : "Error");
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
//
// //TEST 3 - expected: abc
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// addElement(&alist, 'b');
// addElement(&alist, 'c');
// element = findElement(&alist, 'g');
// deleteElement(&alist, element);
// for (LinkedListElement_t* elem=alist.head; elem != NULL; elem = elem->next) {
// printf("%c", elem->data);
// }
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
//TEST 4 - expected: a
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// addElement(&alist, 'b');
// element = findElement(&alist, 'b');
// deleteElement(&alist, element);
// for (LinkedListElement_t* elem=alist.head; elem != NULL; elem = elem->next) {
// printf("%c", elem->data);
// }
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
//
// //TEST 5 - expected: b
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// addElement(&alist, 'b');
// element = findElement(&alist, 'a');
// deleteElement(&alist, element);
// for (LinkedListElement_t* elem=alist.head; elem != NULL; elem = elem->next) {
// printf("%c", elem->data);
// }
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
// // //TEST 6 - expected: abc
// LinkedList_t alist = {.head = NULL, .tail = NULL};
// LinkedListElement_t* element;
// addElement(&alist, 'a');
// addElement(&alist, 'b');
// addElement(&alist, 'c');
// element = (LinkedListElement_t*)calloc(sizeof(LinkedListElement_t), 1);
// element->data = 'g';
// deleteElement(&alist, element);
// for (LinkedListElement_t* elem=alist.head; elem != NULL; elem = elem->next) {
// printf("%c", elem->data);
// }
// //Clean up
// while (alist.head != NULL) {
// deleteElement(&alist, alist.head);
// }
}
void addElement(LinkedList_t* list, char data)
{
LinkedListElement_t* element = calloc(1, sizeof(LinkedListElement_t));
element->data = data;
element->next = NULL;
if (list->tail == NULL) {
list->head = element;
list->tail = element;
} else {
list->tail->next = element;
list->tail = element;
element->next = NULL;
}
}
LinkedListElement_t* findElement(LinkedList_t* list, char data)
{
LinkedListElement_t* element = list->head;
while (element != NULL) {
if (element->data == data) {
return element;
}
element = element->next;
}
return NULL;
}
void deleteElement(LinkedList_t *list, LinkedListElement_t *element)
{
// No Element
if (element == NULL) {
return;
}
// list is empty
if (list->head == NULL) {
return;
}
if (list->head->data == element->data) {
LinkedListElement_t * temp = list->head;
list->head = list->head->next;
free(temp);
if (list->head == NULL) {
list->tail = NULL;
}
} else {
LinkedListElement_t *curr = list->head->next;
LinkedListElement_t *prev = list->head;
while (curr != NULL && curr->data != element->data) {
prev = curr;
curr = curr->next;
}
// element not found
if (curr == NULL) {
return;
}
if (curr->data == element->data) {
prev->next = curr->next;
free(curr);
}
}
}
#endif