LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   wobbly lists in c (https://www.linuxquestions.org/questions/programming-9/wobbly-lists-in-c-653749/)

rubadub 07-05-2008 10:58 AM

wobbly lists in c
 
Hi,
Never being too sure, can you comment on the following implementation of a list, i've wrapped 'em in a struct to be object orientated, but...

main.c
Code:

#include <stdio.h>
#include <stdlib.h>
#include "lists.h"

int main()
{
        struct S_LIST l = slist_init();
       
        char *s = "Hello";
        slist_add(&l, s);
        slist_add(&l, "Good");
        slist_add(&l, "bye");
       
        slist_print(&l);
        printf("count: %d \n", l.count);
       
        slist_delete(&l, 1);
       
        slist_print(&l);
        printf("count: %d \n", l.count);
       
        slist_foreach(&l, print_it);
       
        slist_delete_all(&l);
        slist_print(&l);
       
        return 0;
}

lists.h
Code:

#ifndef S_LIST_H_INCLUDED
#  define S_LIST_H_INCLUDED

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

struct S_LIST
{
        int count;
        struct S_LIST_E *head;
        struct S_LIST_E *tail;
};

struct S_LIST_E
{
        void *data;
        struct S_LIST_E *next;
        struct S_LIST_E *prev;
};


struct S_LIST slist_init()
{
        struct S_LIST l = {0,NULL,NULL};
        return l;
}

void slist_add(struct S_LIST *sl, void *data)
{
        struct S_LIST_E *e;
        if((e = (struct S_LIST_E*) malloc(sizeof(struct S_LIST_E))) != NULL)
        {
                if(sl->head==NULL)
                {
               
                        sl->head = e;
                        sl->tail = sl->head;
                        sl->tail->next = NULL;
                        sl->tail->prev = NULL;
                }
                else
                {
                        sl->tail->next = e;
                        sl->tail->next->prev = sl->tail;
                        sl->tail = sl->tail->next;
                        sl->tail->next = NULL;
                }
                sl->tail->data = data;
                sl->count++;
        }
}

void slist_delete(struct S_LIST *sl, int pos)
{
        struct S_LIST_E *e = sl->head;
        int c = 0;
        while(e!=NULL)
        {
                if(c == pos)
                {
                        struct S_LIST_E *tmp = e;
                        e->prev->next = tmp->next;
                        e->next->prev = tmp->prev;
                        free(e);
                        //free(tmp);
                        sl->count--;
                        return;
                }
                e = e->next;
                c++;
        }
}

void slist_delete_all(struct S_LIST *sl)
{
        struct S_LIST_E *e = sl->head;
        struct S_LIST_E *v = NULL;
        while(e != NULL)
        {
                v = e;
                e = e->next;
                free(v);
        }
        sl->head = NULL;
        sl->tail = NULL;
        sl->count = 0;
}

void slist_print(struct S_LIST *sl)
{
        struct S_LIST_E *e = sl->head;
        while(e!=NULL)
        {
                printf("%s \n", (char*)e->data);
                e = e->next;
        }
}

void print_it(void *s)
{
        printf("%s \n", (char*)s);
}

void slist_foreach(struct S_LIST *sl, void (*func)(void *data))
{
        struct S_LIST_E *e = sl->head;
        while(e!=NULL)
        {
                func(e->data);
                e = e->next;
        }
}
#endif

Just realised there's no insert yet...

Mara 07-05-2008 04:30 PM

Generally fine, but:
1. I'd check if sl (and other parameters) is not NULL at the beginning of (nearly) each function.
2. I'd return some kind of error codes: for instance if the position in slist_delete doesn't make sense.
3. Who frees data when element is deleted? As it is possible for data to keep pointers to other dynamic structures that should be free()'d, there should be a function pointer passed to delete or some other mechanism to handle that (very easy to forget about about doing it before calling slist_delete).

smoked kipper 07-06-2008 04:17 PM

Also, since the code is in a header file, you may want to make the functions static, otherwise when you start including it in more than one source file, you will end up with multiple definitions of each function.


All times are GMT -5. The time now is 03:24 AM.