marianstefi20
marianstefi20

Reputation: 157

Graph representation with dynamic linked lists

I start by saying I am quite new to C and right now, I struggle with some very non intuitive mistakes. I've tried for quite a while now to reach at some solution, but I am always reaching a dead end.

I am trying to build a couple of functions for inserting and displaying a graph via dynamic linked lists. At compile time everything works just fine, but the elements seem not to be well displayed. Actually, just like in the image below, only the first element of the node is displayed.

So the question is what is causing these errors and warnings and what should I do to remove them?

enter image description here

If you take a look at the code below, you will see that it has a few warnings(I don't know why they appear - I am using Code Blocks in Ubuntu with the GNU compiler) and also problems at displaying the elements of the graph. The problem lies most likely in the display_graph function, but I can't realize where.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct AdjListNode {
    int dest;
    struct LIST_NODE *next;
} LIST_NODE;

typedef struct AdjList {
    struct LIST_NODE *head;
} ADJACENCY_LIST;

LIST_NODE *create_node(int dest) {
    LIST_NODE *nod;
    if(dest<0) exit(0);
    nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
    if(nod==NULL) {
        printf("Problems at memory allocation!");
        exit(0);
    }
    nod->dest = dest;
    nod->next = NULL;
    return (LIST_NODE*)nod;
}

void display_graph(ADJACENCY_LIST *v) {
    int s, i;
    LIST_NODE *nod;
    s = sizeof(v);
    for(i=0;i<=s;i++) {
        nod = v[i].head;
        //citeste lista cu head in primul nod
        while(nod!=NULL) {
            printf("Data from node: %d \n", nod->dest);
            nod = nod->next;
        }
    }
}

int main()
{
    int n; //number of graph nodes
    int i; //just a counter
    int dest; dest = -1; //it's actually the "name" of the nodes. They  must all be positive so I started negative
    char c;
    ADJACENCY_LIST *t;
    printf("The number of nodes of the graph: ");
    scanf("%d", &n);
    t = (ADJACENCY_LIST*)malloc(n*sizeof(ADJACENCY_LIST));

    /* We make a loop for the nodes and each node has a while thru which I make the links */
    for(i=0;i<n;i++) {
        c = 'D'; // Initializing
        printf("Specify the links of the node %d with the others:\n", i);
        int contor; contor = 0;
        while(c=='D') {
            LIST_NODE *nod;
            printf("The link with node: ");
            scanf("%d%*c", &dest);
            if(dest>=0){
                 nod = create_node(dest);
                 if(contor==0) t[i].head = (LIST_NODE*)nod; // just make the first node a head node
            } else nod = NULL;
            //verificam daca vrem sa continuam
            printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
            c = getchar();
            contor++; //increment counter
        }
        // inchidem lista
    }
   display_graph(t);
return 0;
}

Any help will be greatly appreciated!

EDIT: As Christhofe(confirmed the problem) and Abhishek Vasisht pointed out the size of the vector v returned actually the size of the pointer.

But, there are still some warnings which I don't know why they still appear...all are

||=== Build: Debug in Grafuri1 (compiler: GNU GCC Compiler) ===| /home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘display_graph’:| /home/marianpc/Anul_1/SDA/Grafuri1/main.c|33|warning: assignment from incompatible pointer type| /home/marianpc/Anul_1/SDA/Grafuri1/main.c|38|warning: assignment from incompatible pointer type| /home/marianpc/Anul_1/SDA/Grafuri1/main.c|28|warning: unused variable ‘s’ [-Wunused-variable]| /home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘main’:| /home/marianpc/Anul_1/SDA/Grafuri1/main.c|71|warning: assignment from incompatible pointer type| /home/marianpc/Anul_1/SDA/Grafuri1/main.c|76|warning: assignment from incompatible pointer type| ||=== Build finished: 0 error(s), 5 warning(s) (0 minute(s), 0 second(s)) ===|

The main thing is the program is functional now. Thanks a lot guys! Really helpful!!

Upvotes: 0

Views: 377

Answers (2)

user3629249
user3629249

Reputation: 16540

the following code compiles cleanly, works.

It does not have the capability of having a list of nodes for each entry in the first level list of pointers.

You can easily add that feature.

You also need to add the feature of passing each malloc'd node to free() especially when an error has occurred

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct AdjListNode
{
    int dest;
    struct AdjListNode *next;
} ;


// declare list of pointers to nodes
static struct AdjListNode **head = NULL;


struct AdjListNode *create_node(int dest)
{
    struct AdjListNode *nod;

    nod = malloc(sizeof(struct AdjListNode));
    if(nod==NULL)
    {
        perror(" malloc failed" );
        printf("Problems at memory allocation!");
        exit(-1);
    }

    // implied else, malloc successful

    nod->dest = dest;
    nod->next = NULL;
    return nod;
} // end function: create_node



int main( void )
{
    int n; //number of graph nodes
    int i; //just a counter
    int dest = -1; //it's actually the "name" of the nodes. They  must all be positive so I started negative


    printf("The number of nodes of the graph: ");
    if( 1 != scanf("%d", &n) )
    { // then scanf failed
        perror( "scanf for number of nodes failed" );
        exit( -1 );
    }

    // implied else, scanf successful

    // set ptr to list of node pointers
    head = malloc(n*sizeof(struct AdjList*));
    if( NULL == head )
    { // then malloc failed
        perror( "malloc failed for list of pointers to nodes" );
        exit( -1 );
    }

    // implied else, malloc successful

    // initialize list of pointers (makes for easier cleanup, especially when a failure occurs
    memset( head, 0x00, n*sizeof(struct AdjList*) );

    /* We make a loop for the nodes and each node has a while thru which I make the links */
    for(i=0;i<n;i++)
    {
        printf("Enter Dest value for %d of %d:", i, n);

        if( 1 != scanf("%d", &dest) ) // note %d will skip over leading white space like newlines
        { // then scanf failed
            perror( "scanf for dest value failed" );
            exit(-1);
        }

        // implied else, scanf successful

        if(dest>=0)
        {
             head[i] = create_node(dest);
        }
        else
        {
            printf( "Dest value must be >= 0\n" );
        }

        //verificam daca vrem sa continuam

        // inchidem lista
    } // end for

    return 0;
} // end function: main

Upvotes: 0

Abhishek Vasisht
Abhishek Vasisht

Reputation: 426

Try this

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct AdjListNode {
    int dest;
    struct LIST_NODE *next;
} LIST_NODE;

typedef struct AdjList {
    struct LIST_NODE *head;
} ADJACENCY_LIST;

LIST_NODE *create_node(int dest) {
    LIST_NODE *nod;
    if (dest < 0) exit(0);
    nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
    if (nod == NULL) {
        printf("Problems at memory allocation!");
        exit(0);
    }
    nod->dest = dest;
    nod->next = NULL;
    return (LIST_NODE*)nod;
}

void display_graph(ADJACENCY_LIST *v,int values) {
    int s, i;
    LIST_NODE *nod;

    for (i = 0; i < values; ++i)
    {
        nod = v[i].head;
        printf("Data from node: %d \n", i);
        while (nod != NULL)
        {
            printf("Data : %d \n", nod->dest);
            nod = nod->next;
        }
    }
}

int main()
{
    int n; //number of graph nodes
    int i; //just a counter
    int dest; dest = -1; //it's actually the "name" of the nodes. They  must all be positive so I started negative
    char* c = (char*)(malloc(sizeof(char)));

    ADJACENCY_LIST *t;
    LIST_NODE *last_added;

    printf("The number of nodes of the graph: ");
    scanf("%d", &n);
    t = (ADJACENCY_LIST*)calloc(n,sizeof(ADJACENCY_LIST));

    /* We make a loop for the nodes and each node has a while thru which I make the links */
    for (i = 0; i < n; i++) {
        //c = 'D'; // Initializing
        printf("Specify the links of the node %d with the others:\n", i);
        int contor; contor = 0;
        do {
            LIST_NODE *nod;
            printf("The link with node: ");
            scanf("%d", &dest);
            if (dest >= 0) {
                nod = create_node(dest);
                if (contor == 0)
                {
                    t[i].head = (LIST_NODE*)nod; // just make the first node a head node
                    last_added = nod;
                }
                else
                {
                    last_added->next = nod;
                    last_added = nod;
                }
            }
            //verificam daca vrem sa continuam
            printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
            fflush(stdin);
            *c = getchar();
            contor++; //increment counter
        } while (*c == 'D');
    }
    display_graph(t,n);
    return 0;
}

Upvotes: 2

Related Questions