Search code examples
cpointersstructmallocdouble-pointer

Code doesn't work when I reference double pointer


Why can't I properly store and reference a double pointer?

This code works:

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

typedef struct _node{
    int nodeNumber;
    int weight;
}* Node;

int main(int argc, char **argv){
    Node nodeList = calloc(3, sizeof(struct _node));

    // Used for testing
    nodeList->nodeNumber = 9;
    printf("Node Number: %d\n", nodeList->nodeNumber);

    return 0;
}

but when I try making the struct a double pointer, and referencing like this:

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

typedef struct _node{
        int nodeNumber;
        int weight;
}** Node;



int main(int argc, char **argv){
        Node nodeList = calloc(3, sizeof(struct _node));

        // Used for testing
        nodeList[0]->nodeNumber = 9;
        printf("Node Number: %d\n", nodeList[0]->nodeNumber);

        return 0;
}

My program runs for a second then crashes. No error or anything. I thought that referencing the struct with

nodeList[0]->nodeNumber = 9;

would work but apparently it does not.

Also I would like to note that I know creating a pointer or double pointer directly in the struct is usually considered bad practice but this is part of an assignment and the struct definition was given and must be used "as is". The ultimate goal is to make an array or linked lists. The linked lists part will be find as I think I understand that but this is the problem.

------------------------------- EDIT ------------------------------------

I have changed my code to this:

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

typedef struct _node{
        int nodeNumber;
        int weight;
}** Node;



int main(int argc, char **argv){
        Node nodeList = malloc(sizeof(struct _node *));

        // Used for testing
        nodeList[0]->nodeNumber = 9;
        printf("Node Number: %d\n", nodeList[0]->nodeNumber);

        return 0;
}

but my program is still crashing.


Solution

  • If you insist on using double pointers, then you should proceed as follows:

    typedef struct _node{
        int nodeNumber;
        int weight;
    } Node;
    

    and in your function:

        Node **nodelist = malloc(3 * sizeof(Node *));
        for (int i=0; i<3; i++)
            nodelist[i]= calloc(1,sizeof(Node));
    

    Note that I don't use pointers in the typedef because it is very confusing. Instead, I declare the nodelist as a double pointer.


    So you professor insists on using a double pointer in the typedef (I suggest you tell your professor to visit stackoverflow.com....). Then proceed as follows:

    typedef struct _node{
        int nodeNumber;
        int weight;
    } **Node;
    

    and in your function:

        Node nodelist = malloc(3 * sizeof(*nodelist));
        for (int i=0; i<3; i++)
            nodelist[i]= calloc(1,sizeof(*nodelist[i]));
    

    Here I don't use the typename but the variable name to determine the size to allocate: the *nodelist dereferences the nodelist to a struct _node * and the *nodelist[i] dereferences that to the actual struct _node (note that the value of i is not important here; it is only used to indicate to the compler that an array element is intended).

    People prefer it even to use the variable name instead of the type name so when in future the variable would refer to another type, the allocation changes automatically with it.