hogni89
hogni89

Reputation: 1754

Generic Linked List in C

I have a linked_list struct:

 typedef struct  linked_list{
        void *data;
        struct linked_list *next;
        struct linked_list *previous;
    } linked_list;

And some linked list operations:

linked_list *init_linked_list() {
    linked_list *ll;
    ll = (linked_list *) malloc(sizeof(linked_list));

    ll->next = ll;
    ll->previous = ll;
    return ll;
}

void add_element( linked_list *list, void *element) {
    linked_list *list_element;

    list_element = malloc(sizeof(linked_list));
    list_element->data = element;

    list_element->next = list->next;
    list->next->previous = list_element ;
    list->next = list_element ;
    list_element->previous = list;
}

I have a graph struct:

typedef struct graph {
    int number_vertices;
    vertex **vertices;
} graph;

I have a vertex struct:

typedef struct vertex {
    int time;
    char *name;
    linked_list *edges;
} vertex;

I have a edge struct:

typedef struct edge{
    int weight;
    int change;
    vertex *to;
} edge;

And an "add-edge" function:

void add_edge_to_vertex(vertex *v,  int weight, int change, vertex *to) {
    edge *pEdge = malloc(sizeof(edge));
    pEdge->weight = weight;
    pEdge->change = change;
    pEdge->to = to;
    // add edge to vertex linked list
    add_element(v->edges, pEdge);
}

Now to my problem. I setup my graph:

int aSize = 30;
int bSize = 30;
pGraph = malloc(sizeof(graph));
pGraph->vertices = malloc(sizeof(vertex*) * aSize);
pGraph->vertices[0] = malloc(sizeof(vertex) * bSize);

I setup my a vertex and init the linked_list:

vertex *pVertex ;
pVertex = malloc(sizeof(vertex));
pVertex->edges = init_linked_list();

And I add the vertex to my graph:

pGraph->vertices[a][b] = *pVertex;

Last I add an edge between two vertices:

add_edge_to_vertex(&pGraph->vertices[a][i], 100, 0, &pGraph->vertices[a][i+1]);

When I try to fetch the edge weight, I get an segment fault: 11

vertex *v = &pGraph->vertices[0][0];
linked_list *ll = v->edges;
int s = linked_list_size(ll);
printf("%d\n", s); // outputs 1 - works so far!
edge *e = (edge *) ll->data;
int weight = e->weight; // segment fault: 11 ..

I have also tried to add an int and a char to the linked_list struct, and fetched that value, instead of fetching (and casting) edge from the "void *data". This works. My problem now is, that I don't know if my fault is when I fetch the data, or when I store the data.

Upvotes: 1

Views: 771

Answers (1)

Sander De Dycker
Sander De Dycker

Reputation: 16243

Your linked list has one extra node at the start that does not have its data member initialized (the node created by the init_linked_list() function).

When you do :

edge *e = (edge *) ll->data;

you get that first node's data member, which is uninitialized. That causes the segmentation fault when you try to dereference e.

Try this instead :

edge *e = (edge *) ll->next->data;

which will get the data member for the node that was inserted by the last add_element function call. Obviously, this is only safe if there has been at least one element added into the linked list.

Upvotes: 2

Related Questions