Search code examples
cpointersstructmallocdynamic-memory-allocation

What is the proper way of pointing to (pointer to structure)?


I have 2 pointers (a and b).
a is my main pointer and I allocated it by malloc.
b is just a pointer and must point to a.
I did it as below:

First code

#include <stdio.h>
#include <stdlib.h>

typedef struct var
{
    int i;
} var;

void main()
{
    var *a = (var *) malloc(sizeof(var));
    var *b = a;

    // Checking what I did is correct and pointers point to each other
    a->i = 123;
    b->i = 456;
    printf("%d %d", a->i, b->i); // output: 456 456
}

But I'm not pretty sure about the way I used pointer b, cause I can get the same result when I use extra allocation for b. See below:

Second code

#include <stdio.h>
#include <stdlib.h>

typedef struct var
{
    int i;
} var;

void main()
{
    var *a = (var *) malloc(sizeof(var));
    var *b = (var *) malloc(sizeof(var)); // extra allocation
    b = a;

    // Checking what I did is correct and pointers point to each other
    a->i = 123;
    b->i = 456;
    printf("%d %d", a->i, b->i); // output: 456 456
}

Q: Is second code correct or just memory-wasting? Should I use allocation when I just want pointing to another pointer?
PS: I know my question is basic but I googled a lot and found nothing.


Solution

  • Lets go over the statements one by one, with some drawings to show where the variables are pointing.

    var *a = (var *) malloc(sizeof(var));
    

    That will be something like this:

    +---+      +-----+
    | a | ---> | ??? |
    +---+      +-----+
    

    [I put ??? because the memory isn't initialized, and its contents is indeterminate]

    Following that we have:

    var *b = (var *) malloc(sizeof(var)); // extra allocation
    

    And now you have:

    +---+      +-----+
    | a | ---> | ??? |
    +---+      +-----+
    
    +---+      +-----+
    | b | ---> | ??? |
    +---+      +-----+
    

    Now you have two memory areas, one from each call to malloc, and a and b are pointing to one each.

    Lastly the assignment:

    b = a;
    

    Now it's like this:

    +---+         +-----+
    | a | ---+--> | ??? |
    +---+    |    +-----+
             |
    +---+    |    +-----+
    | b | --/     | ??? |
    +---+         +-----+
    

    The assignment makes b point to the exact same memory as a is pointing to. The memory allocated by your second call to malloc will be lost, and you will have a memory leak.


    If you really want b to be a pointer to the variable a, you need to make it a pointer to a pointer, and use the pointer-to operator & to get a pointer to a:

    var **b = &a;
    

    With such a definition then it will look like this:

    +---+     +---+      +-----+
    | b | --> | a | ---> | ??? |
    +---+     +---+      +-----+