Search code examples
cscopequeuedynamic-memory-allocation

Is there a difference between dynamically allocated pointer to structure and statically allocated pointer to structure in C?


I was practicing queues and when I tried to created one like this

struct queue
{
  struct node *front;
  struct node *rear;
};
struct queue *q;

and the function that creates the queue

void create_queue(struct queue *q)
{
  q -> rear = NULL;
  q -> front = NULL;
}

it failed at runtime but when I allocated the pointer to the queue inside the function dynamically it worked. like this

struct queue* queue_create(void)
{
  struct queue* q = (struct queue*)malloc(sizeof(struct queue));
  q->rear=NULL;
  q->front=NULL;    
}

Solution

  • In this function

    struct queue* queue_create(void)
    {
      struct queue* q = (struct queue*)malloc(sizeof(struct queue));
      q->rear=NULL;
      q->front=NULL;    
    }
    

    You are not allocating a pointer dynamically as you are saying. The pointer q is a local variable of the function that will not be alive after exiting the function.

    What you are allocating dynamically is an object of the type struct queue. The address of the allocated object is assigned to the local pointer.

    Also what you need is to return the pointer from the function.

    struct queue* queue_create(void)
    {
      struct queue* q = (struct queue*)malloc(sizeof(struct queue));
      q->rear=NULL;
      q->front=NULL;    
    
      return q;
    }
    

    Otherwise there will be a memory leak.

    As for this declaration of a pointer in the file scope

    struct queue *q;
    

    then it is initialized as a null pointer. So using the null pointer in this function to access memory

    void create_queue(struct queue *q)
    {
      q -> rear = NULL;
      q -> front = NULL;
    }
    

    invokes undefined behavior.

    That is what you need to allocate dynamically is an object of the structure type. Where there will be declared a pointer that will point to the allocated object is in fact unimportant. What is important is the pointer must point to a valid object of the structure type. In this case using the pointer you can change data members of the object pointed to by the pointer.