为c struct array

时间:2016-11-20 10:16:13

标签: c memory-management struct

从头开始编写邻接列表时,我面临着为struct数组寻址和分配内存的一些问题。 (忽略有向/无向列表)。
经过数小时的调试后,我发现代码只保留(更新)邻接列表中的最后两个输入。
我想知道实际上是什么以及如何搞乱内存分配并访问它。
请不要忘记给我关于这个主题/问题的进一步研究链接。提前谢谢。
这是我的代码 -

/*a single node of an adjacency list*/
typedef struct adjList{

    int dest;
    struct adjList *next;

} adjList;


/*Image of a graph...*/

typedef struct Image{

    int source;
    adjList *head;

} Image;


void add_adj_edge(Image graph[], int source, int destiny);

int main() {

    int vertices = 6;
    Image graph[vertices];

     //need not to mention detailed here    
   // initialize_graph(graph, vertices);

    add_adj_edge(graph, 1, 2);
    add_adj_edge(graph, 1, 4);
    add_adj_edge(graph, 1, 5);
    add_adj_edge(graph, 1, 6);
    print_graph(graph, vertices);
    printf("graph[1].head->dest: %d\n", graph[1].head->dest);

    return 0;
}





void add_adj_edge(Image *graph, int src, int dest){

    adjList *cache = malloc(sizeof(adjList));
    /*create a single node*/
    cache->dest = dest;
    cache->next = NULL;

    if(graph[src].head == NULL){
            graph[src].head = cache;

    }


    else{

            while( graph[src].head->next != NULL){
                graph[src].head = graph[src].head->next;
            }

            graph[src].head->next = cache;

    }

    return;

}

输出

        node: 1    5 6 
        node: 2    
        node: 3    
        node: 4    
        node: 5    
        node: 6    
        graph[1].head->dest: 5

Instead of 

        node: 1   2 4 5 6
        node: 2    
        node: 3    
        node: 4    
        node: 5    
        node: 6 
        graph[1].head->dest: 2

1 个答案:

答案 0 :(得分:1)

正如我所提到的那样,您的源代码有一些缺失,也误解了如何更新链接列表。

第一个问题:(在Image graph[vertices];中分配main()并未初始化值。)

  

必须将adjList *head;属性设置为NULL才能确定   第一次访问时if(graph[src].head == NULL)为真。

int vertices = 6;
Image graph[vertices];
for(int i=0;i<vertices;i++) {
    graph[i].head = NULL;  // list is empty
    graph[i].source = 0; // or what ever you want
}

第二个问题:(在链表的末尾添加新节点时,需要使用临时变量来探索上一个节点)。

  

如果你使用的是graph[src].head = graph[src].head->next;,你会的   用最后一个节点覆盖所有先前的节点。

add_adj_edge()中使用以下方法来探索节点:

        adjList *pTmp;

        // point to the first node
        pTmp = graph[src].head;
        // explore node until the last has no node
        while( pTmp->next != NULL){
            pTmp = pTmp->next;
        }
        // update the next node
        pTmp->next = cache;