首页 文章

C中的通用链表

提问于
浏览
1

我有一个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 回答

  • 2

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

    当你这样做时:

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

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

    试试这个:

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

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

相关问题