我有一个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。这有效。 我现在的问题是,我不知道我的错误是在获取数据时,还是在存储数据时。
答案 0 :(得分:2)
您的链接列表在开始时有一个额外的节点没有初始化其data
成员(由init_linked_list()
函数创建的节点)。
当你这样做时:
edge *e = (edge *) ll->data;
你得到第一个节点的data
成员,这是未初始化的。当您尝试取消引用e
时,这会导致分段错误。
请改为尝试:
edge *e = (edge *) ll->next->data;
将获取上次data
函数调用插入的节点的add_element
成员。显然,只有在链表中至少添加了一个元素时,这才是安全的。