I supposed to write a long explanation of the code but the explanation is already in the code below so I guess my question is: How do I get it to work without having to malloc then freeing it? or basically what is the correct way to write this in a situation like this?
#include <stdio.h>
#include <malloc.h>
struct d {
int f;
};
struct d* rr() {
struct d* p = malloc(sizeof (struct d*));
p->f = 33;
return p;
}
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
int main()
{
//works..
struct d* g;
g = malloc(sizeof (struct d));
g->f = 45;
printf("[%i]", g->f);
//works..
g = rr();
printf("[%i]", g->f);
//below, both are same, except in this first case, g is allocated then freed..
//works..
free(g);
rr2(g);
printf("[%i]", g->f);
//doesn't work..
struct d *q;
rr2(q);
printf("[%i]", q->f);
return 0;
}
CodePudding user response:
For starters in the both functions
struct d* rr() {
struct d* p = malloc(sizeof (struct d*));
p->f = 33;
return p;
}
and
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
there is a typo. It seems you mean
struct d* p = malloc(sizeof (struct d));
^^^^^^^^
and
p = malloc(sizeof (struct d));
^^^^^^^^^
or
struct d* p = malloc(sizeof ( *p ));
^^^^^
and
p = malloc(sizeof ( *p) );
^^^^^
As for this function
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
then in this call
struct d *q;
rr2(q);
the pointer q
is passed to the function by value. So the function deals with a copy of the pointer q
. Changing the copy within the function does not reflect on the original pointer q
. It stays unchanged.
To make the code working you have to pass the pointer by reference (indirectly through a pointer to it). In this case the function will look like
void rr2(struct d **p) {
*p = malloc(sizeof (struct d ));
( *p )->f = 22;
}
and be called like
rr2( &q );
As for this code snippet
free(g);
rr2(g);
printf("[%i]", g->f);
then it just invokes undefined behavior because in this statement
printf("[%i]", g->f);
there is an access to already freed memory.