Home > Software design >  How to Use Typedef Structure Name with Pointer
How to Use Typedef Structure Name with Pointer

Time:02-19

I am trying to implement a linked list using the given structure for a bigger project. The structure is defined below:

typedef struct node {
   unint32_t size; // = size of the node
   struct node * link; // = .next pointer
} * ListNode;

I was able to implement a linked list using struct node *. But when I attempt to use ListNode like in the following program:

typedef struct node {
    unint32_t size;
    struct node * link;
} * ListNode;


void insert_node (ListNode * head, unint32_t size) {
 ListNode new_node = (ListNode) malloc (sizeof(ListNode));

 new_node->size = size;
 new_node->link = NULL;

 if (head == NULL) {
  head = &new_node;
 }

 else {
  ListNode current = *head;

  while (current->link != NULL) {
   current = current->link;
  }

  current->link = new_node;
 }
}


int main (int argc, char const * argv[]) {
 ListNode head = NULL;
 insert_node (&head, 10);
 insert_node(&head, 20);

 ListNode ptr = head;

 while (ptr != NULL) {
   printf ("%d ", ptr->size);
 }
 printf ("\n");
 
 return 0;
}

I get a segmentation fault. Why is that? It even says that struct node * and ListNode are incompatible pointers/types. I thought they were the same struct just named differently.

CodePudding user response:

A little clarification

typedef struct node {
    unint32_t size;
    struct node * link;
} *ListNode;

creates a type called ListNode. It is a pointer to a struct node. It is not a struct node

So when you do

sizeof(ListNode) 

you get the size of a pointer, not the size of struct node

You needed to do

sizeof(struct node)

A very common thing to do is this

typedef struct node {
    uint32_ size;
    struct node* link;
} *PListNode, ListNode;

this creates 2 types

  • PlistNode which is a pointer to a struct node
  • ListNode which is a struct node

the 'P' is a reminder that this is a pointer

so now you can do

PListNode pn = malloc(sizeof(ListNode));

CodePudding user response:

  • Since you supply a struct node** (a ListNode*) to insert_node, you need to dereference it to assign to it.
  • You malloc the size of a struct node* (a ListNode) but you need to malloc the size of a struct node.
  • You also need to do ptr = ptr->link in the loop in main.

Example:

void insert_node(ListNode* head, uint32_t size) {
    // corrected malloc, you don't want the sizeof a pointer but the
    // size of a `node`:
    ListNode new_node = malloc(sizeof *new_node);

    new_node->size = size;
    new_node->link = NULL;

    if (*head == NULL) {           // corrected check (dereference head)
        *head = new_node;          // corrected assignment
    } else {
        ListNode current = *head;
        while (current->link != NULL) {
            current = current->link;
        }
        current->link = new_node;
    }
}

int main() {
    ListNode head = NULL;
    insert_node(&head, 10);
    insert_node(&head, 20);

    // the below loop had no exit condition before:
    for(ListNode ptr = head; ptr; ptr = ptr->link) {
        printf("%d ", ptr->size);
    }
    printf("\n");
}

Demo

  • Related