С М
С М

Reputation: 13

Memory corruption cause by free()

I'm trying to understand how does dynamic memory allocation in C work. So I coded this:

typedef struct person{
    int id;
    int credit;
}person_t;

typedef struct list{
    int id;
    person_t * people;
}list_t;

int main(){
list_t * list;
list = malloc(sizeof(list_t));
list->people = malloc(10 * sizeof(person_t)); //list for 10 people

free(list->people);
free(list);
}

, which appears to be correct. However, when I decided to create functions for allocation\deallocation, double free or corruption error started to appear:

void init_list(list_t * listptr, int size){
    listptr = malloc(sizeof(list_t));
    listptr->people = malloc(size * sizeof(person_t));
}

void clear_list(list_t * listptr){
    free(listptr->people);
    free(listptr);
}

int main(){
list_t list;
init_list(&list, 10); //list for 10 people
clear_list(&list);
}

Output:

Error in ./list: double free or corruption (out) : 0x00007ffc1b3fba70

Why could that be? Thanks in advance.

Upvotes: 1

Views: 361

Answers (1)

R Sahu
R Sahu

Reputation: 206747

void init_list(list_t * listptr, int size){
    listptr = malloc(sizeof(list_t));
    listptr->people = malloc(size * sizeof(person_t));
}

is not correct. You are modifying listptr in the function. That does not change anything of list in main. You need to remove the line fhat changes listptr in that function. Use:

// listptr is already a valid pointer.
// There is no need to allocate memory for it.
void init_list(list_t * listptr, int size){
    listptr->people = malloc(size * sizeof(person_t));
}

You have a worse mistake in clear_list.

void clear_list(list_t * listptr){
    free(listptr->people);
    free(listptr);
}

You are calling free on a pointer that was not allocated by a call to malloc. listptr is a pointer to the object that was created in stack in main. Remove the second call to free. Use:

// listptr is a pointer to an object on the stack in main.
// Trying to call free on it is an error.
void clear_list(list_t * listptr){
    free(listptr->people);
}

Upvotes: 1

Related Questions