-1

Why when i have to declare a pointer to a node (head) I also have to allocate memory with malloc or calloc for it? I saw that the code that generate a list (not imported here) works well also without allocate memory for it and just declaring node *head.

typedef struct str_node{
    int data;
    struct str_node *next;
}node;

int main(){

    node *head;

    head = (node*) malloc(sizeof(node));
    head = NULL;

And why when I allocate memory like above i have to write (node*)? Isn't it already allocated to a struct node since I'm doing it on head? What is the meaning of that line of code exactly? Moreover when I write head = NULL am I set the address of the pointer head to NULL or what?

9
  • You don't have to write (node*) and many people here strongly recommend that you don't. (It's required in C++, but that's a different language, and in C++ you shouldn't use malloc anyway.) Commented Aug 19, 2020 at 16:33
  • (node*) just cast the result to a pointer to a node, head = NULL clears the list (sets the root to NULL and should not be here because the malloc return value must be freed using free). Commented Aug 19, 2020 at 16:35
  • See Do I cast the result of malloc? Commented Aug 19, 2020 at 16:37
  • Ok but i don't cast the result to a pointer to a node already declaring "head = ...." @רועיאבידן Commented Aug 19, 2020 at 16:41
  • Yes, that's why @rici said, correctly, that you do not have to do it (in C, not C++). Commented Aug 19, 2020 at 16:43

3 Answers 3

1

This code snippet

node *head;

head = (node*) malloc(sizeof(node));
head = NULL;

produces a memory leak.

At first a memory for an object of the type node was allocated and its address was assigned to the pointer head

head = (node*) malloc(sizeof(node));

and then at once the value of the pointer was overwritten.

head = NULL;

As a result the address of the allocated memory was lost and the allocated memory can not be freed.

The code snippet does not make any sense. It will be enough to write

node *head = NULL;

In this case you will initially have an empty list.

And why when I allocate memory like above i have to write (node*)?

The function malloc returns a pointer of the type void *. A pointer of the type void * can be assigned to a pointer of any other object type. So in C the casting is redundant.

In C++ you have explicitly to cast a pointer of the type void * to the type of the object pointer to which the pointer of the type void * is assigned.

Moreover when I write head = NULL am I set the address of the pointer head to NULL or what?

You did not set the address of the pointer itself. The pointer was allocated by the compiler and has the automatic storage duration. You set the value of the variable head that has the type node * to NULL.

Sign up to request clarification or add additional context in comments.

2 Comments

Is it redundant because i already assigned the allocated memory to a node declaring "head = ..." since head is already a node?
@Boninissimo head is a variable of the pointer type node *, Neither object of the type node was created. That is the pointer does not point to any valid object yet.
1

In C, pointers are values, just like integers. When you write:

int a;
a = 3;

you store the value 3 into the variable a.

When you write:

int* p;
p = NULL;

you store the value NULL into the variable p. There is nothing special about pointers. The assignment does not in any way depend on the value of p, i.e. what it might or might not point at. (In this case, it points at nothing, but that's irrelevant.)

malloc returns a pointer to a memory region, which as discussed above is a value. The pointer has no intrinsic metadata; malloc does not require any information beyond the size of the memory region. In particuar, it does not know (or care) what the memory region will be used for. Once that value is produced, you can deal with it as you see fit, for example:

int* p;
p = malloc(sizeof *p);

Since p is declared as a pointer to an int, it is expected that the memory pointed at by p can hold an int. (It doesn't, yet, but it could.) But you can pass around the pointer (as a value) without it having any effect on the integer (if any) stored in the memory pointed to. For example, after

int* q = p;

q and p point at the same memory.

If you find any of this confusing, it is probably because you are expecting a pointer to be something other than a simple value. However, they are simple values and you need a mental model which is based on that simple reality.

Comments

-1

Malloc is used to allocate a block of memory of the specified size i.e. in this case it is (sizeof(node)) which is an 'item' in the linked list. This can be used to allow your linked list to grow.

(node*) is used to allocate the type of memory. Example from GeeksForGeeks

I recommend reading this https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/ It will explain some of the fundamentals.

Finally to answer this "Why when i have to declare a pointer to a node (head) I also have to allocate memory with malloc or calloc for it?".

A pointer points the compiler towards a memory address so when you declare a section of memory using malloc you need to point towards the start of that memory so you can access it (Hence why you need to specify the size so you know how far to read/write).

1 Comment

Please include important code from links in your answer. Links can die and then this information would be lost.

Your Answer

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