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.
