The goal is to write a generic doubly linked list program to handle.
Header:
#include <stdio.h>
#include <stdlib.h>
struct list {
struct node *head;
struct node *tail;
size_t element_size;
int element_count;
void (*printFunc)(struct node *);
};
struct node {
struct node *next;
struct node *previous;
void *data;
size_t type_size;
};
struct node *init_node(void *element, size_t type_size);
struct list *init_list(size_t type_size, void (*printFunc)(struct node *));
void append(void *element, size_t type_size, struct list *l);
void prepend(void *element, size_t type_size, struct list *l);
void print_list(struct list *l);
void print_float(struct node *n);
void print_double(struct node *n);
void print_char(struct node *n);
void print_int(struct node *n);
void print_str(struct node *n);
struct node *poll(struct list *l);
struct node *rm_last(struct list *l);
struct node *peek_front(struct list *l);
struct node *peek_back(struct list *l);
void free_list(struct list *l);
void free_node(struct node *n);
Source:
#include "linked_list.h"
int main(int argc, char **argv) {
char array[5] = {'a', 'b', 'c', 'd', 'e'};
struct list *l = init_list(sizeof(char), &print_char);
for (int i = 0; i < 5; i++) {
prepend(&array[i], sizeof(char), l);
}
print_list(l);
free_list(l);
return 1;
}
struct node *init_node(void *element, size_t type_size) {
struct node *n = malloc(sizeof(struct node));
n->data = malloc(type_size);
if (n != NULL && n->data != NULL) {
n->data = element;
n->next = NULL;
n->previous = NULL;
n->type_size = type_size;
}
return n;
}
// creates linked list with dummy head/tail
struct list *init_list(size_t type_size, void (*pf)(struct node *)) {
struct list *l = malloc(sizeof(struct list));
if (l != NULL) {
l->head = NULL;
l->tail = NULL;
l->element_size = type_size;
l->element_count = 0;
l->printFunc = pf;
}
return l;
}
void prepend(void *element, size_t type_size, struct list *l) {
struct node *n = init_node(element, type_size);
if (n != NULL) {
if (l->element_count != 0) {
struct node *tmp = l->head;
n->next = l->head;
l->head = n;
tmp->previous = n;
}
else {
l->head = n;
l->tail = n;
}
l->element_count += 1;
}
}
void append(void *element, size_t type_size, struct list *l) {
struct node *n = init_node(element, type_size);
if (n != NULL) {
if (l->element_count != 0) {
struct node *tmp = l->tail;
n->previous = l->tail;
l->tail = n;
tmp->next = n;
}
else {
l->head = n;
l->tail = n;
}
l->element_count += 1;
}
}
void print_float(struct node *n) {
printf("%f\n", *((float *) n->data));
}
void print_double(struct node *n) {
printf("%lf\n", *((double *) n->data));
}
void print_char(struct node *n) {
printf("%c\n", *((char *) n->data));
}
void print_int(struct node *n) {
printf("%d\n", *((int *) n->data));
}
void print_str(struct node *n) {
printf("%s\n", *((char **) n->data));
}
// Removes node from front of linked list. Does not free memory assoc. with node.
struct node *poll(struct list *l) {
struct node *n = NULL;
if (l->element_count > 0) {
n = l->head;
l->head = n->next;
l->head->previous = NULL;
l->element_count -= 1;
}
return n;
}
// Removes node from tail of linked list.
struct node *rm_last(struct list *l) {
struct node *n = NULL;
if (l->element_count > 0) {
n = l->tail;
l->tail = n->previous;
l->tail->next = NULL;
l->element_count -= 1;
}
return n;
}
struct node *peek_front(struct list *l) {
return l->head;
}
struct node *peek_back(struct list *l) {
return l->tail;
}
void print_list(struct list *l) {
struct node *cur = l->head;
while (cur != NULL) {
l->printFunc(cur);
cur = cur->next;
}
}
void free_list(struct list *l) {
struct node *n = l->head;
while(n) {
struct node *tmp = n;
n = n->next;
//free(tmp->data);
tmp->previous = NULL;
tmp->next = NULL;
free(tmp);
}
}
/*
void free_node(struct node **n) {
struct node *tmp = *n;
free(tmp->data);
tmp->previous = NULL;
tmp->next = NULL;
free(tmp);
}
*/
Questions:
Are there any memory leaks that
free_list
is missing?Is there any need to keep track of the size of the data type stored by the node or the size of the data type in the list
struct
?
free_list
but running Valgrind gives some memory leak errorsinit_node
andinit_list
... – Dair Aug 24 at 5:58