2

I have a type node whose pointer is being used in another struct as shown below.

typedef struct element {
    void* data;
    struct element *next;
} node;

typedef struct queue {
    node *tail;
    node *head;
    int num_items;
} queue_t;

I create an empty queue using the following code, but I am not sure if head and tail should be set to NULL since temp is not pointing anywhere yet.

queue_t *temp;
temp = malloc(sizeof(queue_t));
if (temp == NULL){
return NULL;
}
temp->head = NULL;
temp->tail = NULL;
temp->num_items = 0;

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 address space does not contain a valid queue element yet. So how are temp->head = NULL; and temp->tail = NULL; valid statements? Can someone please explain why this works?

3
  • If you say "C" in the title, don't tag with C++ too. Choose a language; stick with it. Commented Sep 20, 2016 at 4:23
  • 1
    You don't have a struct Node in the code; you have a struct element also known as a node, and you have a struct queue also known as a queue_t. Commented Sep 20, 2016 at 4:24
  • 2
    You allocated a 'struct queue' (aka a queue_t), and then you set the values of the member variables in the struct you allocated. Why wouldn't it work? (Perhaps you read something about the bytes in the allocated space being undefined? That's true, but it's only a problem if you read the undefined values, not if you overwrite them) Commented Sep 20, 2016 at 4:27

4 Answers 4

2

The address space does not contain a valid queue element yet.

Correct, the allocated memory only contains a queue_t

So how are temp->head = NULL; and temp->tail = NULL; valid statements?

head and tail are not part of struct element. head and tail are part of queue_t. You have allocated a queue_t so it is OK to assign values to head and tail. In this case you assign the NULL value to show that they don't point to anything valid yet.

When you allocate a node (aka struct element) you update head and tail like:

// Add first node
temp->head == malloc(sizeof(node));
temp->tail == temp->head;
if (temp->head == NULL){
    return NULL;
}
temp->num_items = 1;

// Initialize the new node
temp->head->next = NULL;   
temp->head->data = NULL;   

// Note: Adding more node requires more complex code
Sign up to request clarification or add additional context in comments.

Comments

0

What is the definition of a "valid queue element"? If it's "sufficient space to hold a queue element and where the locations that hold the head and tail pointers have valid values", then setting them, to NULL makes it valid. If it's not that, what is it?

Comments

0

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.

Correct.

The address space does not contain a valid queue element yet.

Not sure what you what you meant by "valid", but that statement is also correct.

So how are temp->head = NULL; and temp->tail = NULL; valid statements?

It is precisely those statements that makes your allocated space a valid queue element!

Can someone please explain why this works?

Your question fundamentally is no different from a statement such as int i;. Your implementation sets aside a space to hold an integer. However, it is as yet invalid because you have not given it any (meaningful) value. Once you set i = 0; or i = 42;, the space that you call i is now a valid integer.

Hope that helps.

Comments

0

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.