Home > Back-end >  Free memory by external function
Free memory by external function

Time:08-02

Inside main() I made pointer p and allocated it by malloc(); then I set its internal value (data) to 222. For some reason I need a function which:
First: frees the memory of the pointer.
Second: makes the pointer point to new structure. I did it by bar function. (It works properly and the output is correct.)

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct foo_s
    {
        int data;
    } foo;
    
    void bar(foo *f)
    {
        free(f);
    
        foo *g = malloc(sizeof(foo));
        g->data = 333;
    
        f = g;
    }
    
    int main()
    {
       foo *p = malloc(sizeof(foo));
       p->data = 222;
    
       bar(p);
       printf("%d", p->data);
    }
    // output is 333

but when I move free to several few lines below (somewhere that shouldn't change the result), the output shows something else.

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

typedef struct foo_s
{
    int data;
} foo;

void bar(foo *f)
{
    foo *g = malloc(sizeof(foo));
    g->data = 333;

    free(f); // moved here

    f = g;
}

int main()
{
   foo *p = malloc(sizeof(foo));
   p->data = 222;

   bar(p);
   printf("%d", p->data);
}
// output is 7149104

Where is the problem? Why aren't the results the same?

CodePudding user response:

Your bar() function frees the address passed to it, but in main(), after calling bar(p), p still points to the old, now-freed memory address. Dereferencing that is undefined behavior; all sorts of things might happen from seeing the old number, the new number, some random value, your program might crash or summon nasal demons... basically, you can't do that. bar() needs to take a pointer to a pointer so it can modify a variable in the caller's scope:

void bar(foo **f)
{
    foo *g = malloc(sizeof(foo));
    g->data = 333;

    free(*f);

    *f = g;
}

and then be called as bar(&p). Alternatively, bar() can return the new address, and be used as p = bar(p);.

CodePudding user response:

void bar(foo *f)
{
    foo *g = malloc(sizeof(foo));
    g->data = 333;

    free(f); // moved here

    f = g;
}

All the free & malloc magic is not needed. Why to alloc new memory if you already have it for this type? Makes no sense at all.

void bar(foo *f)
{
    f->data = 333;
}
  • Related