Home > Net >  can't reference a struct pointer to function unless it has been previously allocated (and freed
can't reference a struct pointer to function unless it has been previously allocated (and freed

Time:05-21

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.

  • Related