The following code gives a crash stating double free. How to fix this with leaving no memory leaks? Trying to copy contents of tmp to list. Removing free from get_copy gives no crash. But that will result in a memory leak. How to solve this
We are allocating memory thrice here(ignoring loops), so it's being freed three times. memcpy will copy memory and not the contents, I understand. But then, how do I release memory that was allocated previously? Seems the info provided should be sufficient to understand the problem here. But Stackoverflow is not letting me post without adding more text. So, I am writing nothing useful. Please ignore the last paragraph and help to solve the query. This is a crash while freeing memory after memcpy in the case of nested pointers.
#include <stdio.h>
#include <stdlib.h>
typedef struct s1_ {
int x,y,z;
} tmp_type;
typedef struct s2_ {
tmp_type* p1;
char a;
} tmp_data;
typedef struct s3_ {
tmp_data* v1;
int num;
} tmp_list;
void get_copy(tmp_list *list) {
tmp_data tmp[10];
int i;
for(i=0;i<10;i++){
tmp[i].p1= calloc(1,sizeof(tmp_type));
tmp[i].p1->x = tmp[i].p1->y = tmp[i].p1->z = 6;
tmp[i].a = 'a'+i;
}
list->num = 5;
list->v1 = calloc(5,sizeof(tmp_data));
for(i=0;i<5;i++) {
list->v1[i].p1 = calloc(1,sizeof(tmp_type));
}
memcpy(list->v1,tmp,sizeof(list->v1));
for(i=0;i<5;i++) {
memcpy((list->v1[i].p1), (tmp[i].p1), sizeof(tmp_type));
free(tmp[i].p1);
}
}
void main()
{
tmp_list l1;
int i;
get_copy(&l1);
for (i=0;i<l1.num;i++) {
printf("list: %c %d %d %d\n",
l1.v1[i].a,
l1.v1[i].p1->x,
l1.v1[i].p1->y,
l1.v1[i].p1->z);
}
for(i=0;i<l1.num;i++){
free(l1.v1[i].p1);
}
free(l1.v1);
}
First, you should have clarified your expected output rather than cribbing about SO's text limit in question. Your current code (after removing free) gives this output.
But if I am right, you are expecting this output.
memcpy(list->v1,tmp,sizeof(list->v1));isn't really doing what are you thinking. It's just copying the first few bytes of tmp as sizeof (list->v1) is the size of tmp_data pointer. To fix this, you can either use one of the below.memcpy(list->v1,tmp,sizeof(list->v1));withmemcpy(list->v1,tmp,5*sizeof(tmp_data));and remove the next loop.memcpy(list->v1,tmp,sizeof(list->v1));from your code and add thislist->v1[i].a=tmp[i].a;in your loop after memcpy.Now, coming back to your memory management question. If you go with the first one, you don't need a free() to free the first five entries of tmp as p1's pointer will be copied to list->v1, and you are freeing them eventually in main. However, you need to free the last five tmp->p1.
If you choose the second one, you must free all tmp and list entries.
You can find corrected codes here: first second