As per my understanding, malloc will only make temp point to some address space whose size is equal to the size of the struct queue_t.
The malloc function call returns an address to the beginning of the allocated memory of size specified in the argument of malloc function call(in bytes). The allocated memory space will be of size specified in the argument of the malloc. However, the address returned by malloc will be the beginning of that memory space. Therefore, you can access upto the size of the memory space safely using the pointer to that memory space.
The address space does not contain a valid queue element yet.
The C Standard library has allocated a valid memory space for your pointer variable temp to point to. However, the values stored at that memory space could be garbage. Therefore, the pointer to node and num_items data members which have some valid memory space allocated to them within your queue_t may have garbage value. For example, after allocating the memory for queue_t, you can try to print the value of num_items using printf function.
queue_t *temp = malloc(sizeof(queue_t));
if (temp == NULL){
return NULL;
}
printf("The value of num_items: %d\n", temp->num_items);
The above example may print any garbage value. Since, C language doesn't have constructors to initialize newly created variables, you should initialize every variable you create with some stable value.
You can also use calloc function call which also sets allocated memory to zero after allocating the memory space.
So how are temp->head = NULL; and temp->tail = NULL; valid statements?
The memory is allocated by malloc which may contain any garbage value. The data members of queue_t share that memory space. Since, memory space can have garbage data, the data members will be having any random garbage data. That's why it is a good approach to initialize data members of the struct allocated by malloc to some stable values. That's what you have done in your program.
Actually, temp's data members head and tail should point to the addresses of variables of type node. The malloc call has allocated the pointer variables. These pointer variables can point to any variable of type node (or store the address of variable of type node). But you haven't allocated any node variable yet and you don't want to create dangling pointer. Therefore, you should initialize these pointer variables with NULL.
Your program should look like this:
queue_t *temp;
temp = malloc(sizeof(queue_t));
if (temp == NULL){
return NULL;
}
temp->head = NULL;
temp->tail = NULL;
temp->num_items = 0;
//Allocate some node
node *n = malloc(sizeof(node));
int data = 1;
n->data=&data;
n->next=NULL;
temp->head=n;
temp->tail=n;
temp->num_items=1;
struct Nodein the code; you have astruct elementalso known as anode, and you have astruct queuealso known as aqueue_t.