Home > Back-end >  What is the proper way of pointing to (pointer to structure)?
What is the proper way of pointing to (pointer to structure)?

Time:07-20

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.

CodePudding user response:

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 | ---> | ??? |
 ---       ---        ----- 

CodePudding user response:

This code snippet

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

produces a memory leak. At first a memory was allocated and its address was assigned to the pointer b

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

and then the pointer b was reassigned with the value stored in the pointer a.

b = a;

So now the both pointers point to the same object.

The difference between the two programs is that this record in the second program

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

apart from the declaration of the pointer b has no effect except of the produced memory leak. A memory was allocated and its address at once was lost. So the memory becomes inaccessible.

Pay attention to that according to the C Standard the function main without parameters shall be declared like

int main( void )

CodePudding user response:

I think you missed the point in pointers. They are variables like your int and do not need allocation to hold a value.

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

What you do here is create a memory location for the struct, similar to var my_struct; (except it is in different memory), and then saving its location to a so var *a = &my_struct.

var *a itself doesn't need to be allocated, cause it is already allocated when you declared it, as is var *b, and so you can make b point to a without any further steps to prepare it.


So you could for your example code do something like

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

typedef struct var
{
    int i;
} var;

void main()
{
    var my_struct;
    var *a = &my_struct;
    var *b;
    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
}

  • Related