C中的通用链表

时间:2015-03-04 09:59:40

标签: c generics struct linked-list

我有一个linked_list结构:

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

以及一些链表操作:

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;
}

我有一个图形结构:

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

我有一个顶点结构:

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

我有一个边缘结构:

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

还有一个“附加边缘”功能:

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);
}

现在我的问题。我设置了我的图表:

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

我设置了一个顶点并初始化了linked_list:

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

我将顶点添加到我的图表中:

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

最后,我在两个顶点之间添加了一条边:

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

当我尝试获取边缘权重时,我得到一个段错误: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 ..

我还尝试在linked_list结构中添加一个int和一个char,并获取该值,而不是从“void * data”中获取(和转换)edge。这有效。 我现在的问题是,我不知道我的错误是在获取数据时,还是在存储数据时。

1 个答案:

答案 0 :(得分:2)

您的链接列表在开始时有一个额外的节点没有初始化其data成员(由init_linked_list()函数创建的节点)。

当你这样做时:

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

你得到第一个节点的data成员,这是未初始化的。当您尝试取消引用e时,这会导致分段错误。

请改为尝试:

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

将获取上次data函数调用插入的节点的add_element成员。显然,只有在链表中至少添加了一个元素时,这才是安全的。