-
-
Save meylingtaing/11018042 to your computer and use it in GitHub Desktop.
A generic linked list library for C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* llist.c | |
* Generic Linked List implementation | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include "llist.h" | |
llist *llist_create(void *new_data) | |
{ | |
struct node *new_node; | |
llist *new_list = (llist *)malloc(sizeof (llist)); | |
*new_list = (struct node *)malloc(sizeof (struct node)); | |
new_node = *new_list; | |
new_node->data = new_data; | |
new_node->next = NULL; | |
return new_list; | |
} | |
void llist_free(llist *list) | |
{ | |
struct node *curr = *list; | |
struct node *next; | |
while (curr != NULL) { | |
next = curr->next; | |
free(curr); | |
curr = next; | |
} | |
free(list); | |
} | |
// Returns 0 on failure | |
int llist_add_inorder(void *data, llist *list, | |
int (*comp)(void *, void *)) | |
{ | |
struct node *new_node; | |
struct node *curr; | |
struct node *prev = NULL; | |
if (list == NULL || *list == NULL) { | |
fprintf(stderr, "llist_add_inorder: list is null\n"); | |
return 0; | |
} | |
curr = *list; | |
if (curr->data == NULL) { | |
curr->data = data; | |
return 1; | |
} | |
new_node = (struct node *)malloc(sizeof (struct node)); | |
new_node->data = data; | |
// Find spot in linked list to insert new node | |
while (curr != NULL && curr->data != NULL && comp(curr->data, data) < 0) { | |
prev = curr; | |
curr = curr->next; | |
} | |
new_node->next = curr; | |
if (prev == NULL) | |
*list = new_node; | |
else | |
prev->next = new_node; | |
return 1; | |
} | |
void llist_push(llist *list, void *data) | |
{ | |
struct node *head; | |
struct node *new_node; | |
if (list == NULL || *list == NULL) { | |
fprintf(stderr, "llist_add_inorder: list is null\n"); | |
} | |
head = *list; | |
// Head is empty node | |
if (head->data == NULL) | |
head->data = data; | |
// Head is not empty, add new node to front | |
else { | |
new_node = malloc(sizeof (struct node)); | |
new_node->data = data; | |
new_node->next = head; | |
*list = new_node; | |
} | |
} | |
void *llist_pop(llist *list) | |
{ | |
void *popped_data; | |
struct node *head = *list; | |
if (list == NULL || head->data == NULL) | |
return NULL; | |
popped_data = head->data; | |
*list = head->next; | |
free(head); | |
return popped_data; | |
} | |
void llist_print(llist *list, void (*print)(void *)) | |
{ | |
struct node *curr = *list; | |
while (curr != NULL) { | |
print(curr->data); | |
printf(" "); | |
curr = curr->next; | |
} | |
putchar('\n'); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* llist.h | |
* Generic Linked List | |
*/ | |
struct node { | |
void *data; | |
struct node *next; | |
}; | |
typedef struct node * llist; | |
/* llist_create: Create a linked list */ | |
llist *llist_create(void *data); | |
/* llist_free: Free a linked list */ | |
void llist_free(llist *list); | |
/* llist_add_inorder: Add to sorted linked list */ | |
int llist_add_inorder(void *data, llist *list, | |
int (*comp)(void *, void *)); | |
/* llist_push: Add to head of list */ | |
void llist_push(llist *list, void *data); | |
/* llist_pop: remove and return head of linked list */ | |
void *llist_pop(llist *list); | |
/* llist_print: print linked list */ | |
void llist_print(llist *list, void (*print)(void *data)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "llist.h" | |
#define COUNT sizeof numbers / sizeof (int) | |
#define COUNT2 sizeof more_numbers / sizeof (int) | |
int numcmp(void *, void *); | |
void numprint(void *); | |
int main() | |
{ | |
int numbers[] = {3, 8, 23, 1, 8, 45, 3, 11, 15, 12, 42, 9, 0, 53, 15}; | |
int more_numbers[] = {7, 10, 4, 11}; | |
llist *my_list = llist_create(NULL); | |
unsigned int i; | |
// Print out the empty list | |
llist_print(my_list, numprint); | |
// Add all of the numbers | |
for (i = 0; i < COUNT; i++) | |
llist_add_inorder((void *)(numbers + i), my_list, numcmp); | |
// Print out list of sorted numbers | |
llist_print(my_list, numprint); | |
// Remove first five numbers | |
for (i = 0; i < COUNT2; i++) | |
llist_pop(my_list); | |
// Print list again | |
llist_print(my_list, numprint); | |
// Add numbers to front | |
for (i = 0; i < COUNT2; i++) | |
llist_push(my_list, &more_numbers[i]); | |
// Print list once again | |
llist_print(my_list, numprint); | |
// Free the list | |
llist_free(my_list); | |
return 0; | |
} | |
int numcmp(void *a, void *b) | |
{ | |
if (*(int *)a < *(int *)b) | |
return -1; | |
if (*(int *)a > *(int *)b) | |
return 1; | |
return 0; | |
} | |
void numprint(void *num) | |
{ | |
int *pnum = (int *)num; | |
if (num == NULL) | |
return; | |
printf("%d", *pnum); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
llist_driver: llist.o main.c | |
gcc -Wall -Wextra llist.o main.c -o llist_driver | |
llist.o: llist.h llist.c | |
gcc -Wall -Wextra -fPIC llist.h -c llist.c | |
clean: | |
rm -rf *.o *.gch llist_driver |
Yes, it is.
llist_pop() causes seg fault if passed llist is NULL.
This can be easly fixed by changing line 113
if (list == NULL || head->data == NULL)
to
if (list == NULL || !head || head->data == NULL)
Then it will just return NULL instead.
llist *new_list = (llist *)malloc(sizeof (llist)); *new_list = (struct node *)malloc(sizeof (struct node));
Is this leaky ?
@MartinChekurov @bwack
How might you go about tweaking this
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is this leaky ?