Neethan
Neethan

Reputation: 3

Unable to free a child of a parent struct

I'm having a weird bug where I can't free() a struct that I malloc()'d RAM for.

I have a struct parent and child, where child is a struct of int. I use malloc() to allocate ram for both the parent and the child structs (where the child struct is malloc() to the size of an array of the child struct). I then use memcpy to copy the array over to the parent struct.

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

typedef struct child child_t;
typedef struct parent parent_t;

struct child {
    int item;
};

struct parent {
    child_t *_child;
};

child_t list[] = {
    { .item = 1 },
    { .item = 2 },
    { .item = 3 },
};

int main(void) {
    parent_t *_parent = malloc(sizeof(parent_t));

    _parent->_child = malloc(sizeof(list));
    memcpy(&_parent->_child, &list, sizeof(list));

    free(_parent->_child);
    free(_parent);
    printf("success\n");
    return 1;
}

free(_parent->_child); just ends up giving me Aborted (core dumped) as an error. I've checked the ram usage, and I can tell that I should be freeing the child, but I'm not sure how to do so.

Upvotes: 0

Views: 295

Answers (2)

Davide Spataro
Davide Spataro

Reputation: 7482

memcpy(&_parent->_child, &list, sizeof(list)); is the problem.

Try with:

memcpy(_parent->_child, list, sizeof(list));

The signature of memcpy is:

void *memcpy(void *str1, const void *str2, size_t n)

and you are passing a pointer to a pointer instead.

This triggers undefined behaviour because your buffers contains trash basically which free() can't use.

Upvotes: 0

Weather Vane
Weather Vane

Reputation: 34560

You should remove the &s from the memcpy statement. _parent->_child is already an address, and the array list[] will decay to a pointer. The effect of what you are doing is to overwrite the pointer member itself (and other) instead of the memory it is pointing to.

memcpy(_parent->_child, list, sizeof(list));

That is why you can't

free(_parent->_child);

because you trashed the pointer you are trying to free.

Upvotes: 6

Related Questions