Home > other >  C - Unable to free a malloced struct
C - Unable to free a malloced struct

Time:02-23

I am attempting to create a simple family tree program in C, however I am encountering an issue where an instance of the following struct refuses to be free and i am getting a memory leak

typedef struct Person {
    struct person* *parents[2];
    struct person* partner;
    struct person* *children[32];
} person;

the accompanying struct which encompasses it is this

typedef struct Tree {
    person* top;
    person* current;
} tree;

the Tree struct frees just fine, however when I attempt to free the malloced memory of the person struct, I get a memory leak I am pretty sure indicates that memory.

void newPerson(tree *t){
    person *p = malloc(sizeof(person));
...

this is the function where the memory is malloced

...
if (t->current){
t->top = p; 
t->current = p; 
...

within the same function, both pointers are set to point to p.

int main(){
    tree *t = malloc(sizeof(tree));
    t->current = NULL;
    newPerson(t);
    free(t->current);
    free(t);
    return 0;
}

And this is the code within the main function where the tree variable is created, and where it is freed. From the various ways ive been trying to fix this, the following happened.

  1. If I put free(p) within the same function the Person is created, everything works fine and there are no errors nor memory leaks
  2. If I try to free t->current, I get a leak sanitiser error telling me of a direct leak exactly where the Person is allocated
  3. If i try to free t->top, I get a SEGV on unknown address error.

Now I know the issue is somewhere with t, but I have the faintest of clue as to what the issue actually is, either my knowledge of malloc and free has degraded to the point where im doing something wrong and i can't see it, or something else is going on.

Edit: Reprex

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

typedef struct Branch {
    struct branch* otherbranch;
} branch;

typedef struct Tree {
    branch* root;
    branch* current;
} tree

void newBranch(tree *t){
    branch *b = malloc(sizeof(branch));
    b->otherbranch = NULL;
    if (t->current){
        t->root = b; 
        t->current = b; 
    }
    //free(b); //case 1 where freeing works
}

int main(){
    tree *t = malloc(sizeof(tree));
    t->current = NULL;
    newBranch(t);
    free(t->root); //case 3 where segv occurs
    //free(t->current); //case 2 where memory leak occurs
    free(t);
    return 0;
}

CodePudding user response:

when you enter this code

void newBranch(tree *t){
    branch *b = malloc(sizeof(branch));
    b->otherbranch = NULL;
    if (t->current){
        t->root = p; 
        t->current = p; 
    }
    //free(b); //case 1 where freeing works
}

t->current is null, so you never set t->root or t->current.

you then return to main and do free(t->root), t->root is invalid at this point. You probably want to initialize t->root to NULL and maybe t->current too

i also assume you mean t->root = b not = p since there is no p i can see

  • Related