在C中基于具有邻接列表的数据初始化Graph时出现问题

时间:2011-02-04 23:48:52

标签: c pointers graph initialization structure

之前我玩过Graphs并且在StackOverflow的帮助下管理好了但是我从未使用过类似下面的结构。我似乎无法理解我在这里做错了什么......

#include "stdio.h"
#include "stdlib.h"

#define MaxV 100
#define MaxE 50

typedef struct edge {
    int dest;
    int cost;

    struct edge *next;
} Edge, *Graph[MaxV];

Graph *initGraph() {    
    Graph *g = (Graph*)malloc(sizeof(Edge) * MaxV);

    for(int i = 0; i < MaxV; i++)
        (*g[i])->next = NULL;

    return g;
}

int main(void) {
    Graph *g = initGraph();

    for(int i = 0; i < MaxV; i++) {
        if((*g[i])->next == NULL) printf("[%02d] NULL\n", i);
    }

    return 0;
}

我在(*g[i])->next = NULL;的第一次迭代中遇到了分段错误,我无法理解为什么。我已经尝试了无数的东西,但我似乎无法用这种结构来管理Graph初始化。另外,我是这样宣布并返回指向Graph的指针的方式是否正确地为这个结构做了什么?

我是否在init函数中使用了很多指针使事情变得复杂或什么?

P.S:请不要提出不同的结构定义,我不能改变上面的任何内容。这是真正的问题。我知道如何使用Graphs滚动我自己的结构,但我需要使用上面的那个。

3 个答案:

答案 0 :(得分:2)

我真的不明白你的*Graph[MaxV]的第二个typedef。

我要做的是声明另一个结构如下:

typedef struct graph {
    Edge *edges;
} Graph;

然后您可以按如下方式初始化图表:

Graph *initGraph() {  
    Graph *g = (Graph*)malloc(sizeof(Graph));

    g->edges = (Edge*)malloc(sizeof(Edge) * MaxV);
    for(int i = 0; i < MaxV; i++)
        g->edges[i].next = NULL;

    return g;
}

打印图表如下:

for(int i = 0; i < MaxV; i++) {
    if(g->edges[i].next == NULL) printf("[%02d] NULL\n", i);
}

我认为你会发现,随着时间的推移,图表的额外结构也将更加可持续。 :)

答案 1 :(得分:0)

如果OP要求不以任何方式更改typedef,请完整修改答案。

我建议改为:

void initGraph(Graph g) {
    g[0] = malloc(sizeof(Edge) * MaxV);

    for(int i = 0; i < MaxV; i++)
        g[0][i].next = NULL;
    return;
}

int main(void) {
    Graph g;
    initGraph(g);

    for(int i = 0; i < MaxV; i++) {
        if(g[0][i].next == NULL) printf("[%02d] NULL\n", i);
    }

    free(g[0]);
    return 0;
}

这里的问题是“指针阵列”综合症。即Graph** g等同于Graph *g[10],其明显的条件是外部数组大小是固定的。这会因您can't return a fixed size array而产生问题,但您可以返回**

我仍然不确定图形数组的用例是什么,但是,这会传递valgrind。

答案 2 :(得分:0)

我想我找到了我想要的解决方案。我尽可能地使用Valgrind来测试读/写权限,并且没有错误。是的,有内存泄漏,但这不是这个问题的重点(我知道这些,不要担心)。

这是创建简单图表的完整代码。很想听听这个实施可能会遇到的任何问题......

#include "stdio.h"
#include "stdlib.h"

#define MaxV 10
#define MaxE 5

typedef struct edge {
    int dest;
    int cost;

    struct edge *next;
} Edge, *Graph[MaxV];

Graph *initGraph() {
    Graph *g = (Graph*)malloc(sizeof(Graph));

    for(int i = 0; i < MaxV; i++)
        (*g)[i] = NULL;

    return g;
}

int insertEdge(Graph *g, int o, int d, int c) {
    if(!g) return -1;

    Edge *edge = (Edge*)malloc(sizeof(Edge));

    edge->dest = d;
    edge->cost = c;

    edge->next = (*g)[o];
    (*g)[o] = edge;

    return 0;
}

int main(void) {
    Graph *g1 = initGraph();
    Edge *aux = NULL;

    insertEdge(g1, 0, 1, 2);
    insertEdge(g1, 0, 2, 3);
    insertEdge(g1, 1, 4, 5);
    insertEdge(g1, 2, 4, 1);
    insertEdge(g1, 4, 8, 6);

    for(int i = 0; i < MaxV; i++) {
        printf("[%02d]\n", i);

        for(aux = (*g1)[i]; aux != NULL; aux = aux->next)
            printf(" [%d] » [%d] (%d)\n", i, aux->dest, aux->cost);
    }

    return 0;
}