含指针的嵌套结构Memcpy引发double free的无泄漏修复方案
解决C代码中的Double Free崩溃与内存泄漏问题
问题描述
这段C代码运行时触发double free崩溃,需求是把栈上数组tmp的内容复制到list结构体中。若删除get_copy函数里的free(tmp[i].p1)可避免崩溃,但会造成内存泄漏。已知代码存在三次内存分配(忽略循环)导致重复释放,也清楚memcpy仅复制内存值而非深层内容,但不知道如何正确释放先前分配的内存。
问题根源
- 指针覆盖引发双重释放:
你先通过calloc给list->v1[i].p1分配了内存,随后执行memcpy(list->v1, tmp, sizeof(list->v1))——这里sizeof(list->v1)是指针的大小(64位系统下为8字节),无法完成5个tmp_data的完整复制。更关键的是,即便长度正确,该操作会直接把tmp[i].p1的指针值复制到list->v1[i].p1中,覆盖掉之前calloc生成的指针,造成内存泄漏。之后你free(tmp[i].p1),相当于提前释放了list->v1[i].p1指向的内存,到main函数中再次free(l1.v1[i].p1)时,就触发了double free。 - memcpy长度错误:
sizeof(list->v1)获取的是指针大小,而非5个tmp_data的总字节数,正确长度应为sizeof(tmp_data) * list->num。
两种解决方案
方案1:转移内存所有权(避免重复分配)
既然tmp是栈上数组,前5个元素的p1指向堆内存,我们可以直接将这些指针的所有权转移给list->v1,无需为list->v1[i].p1重新分配内存,既不会泄漏也不会重复释放:
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; // 仅分配存放5个tmp_data的空间,无需单独给p1分配内存 list->v1 = calloc(list->num, sizeof(tmp_data)); // 复制前5个tmp_data的完整内容(包括a字段和p1指针) memcpy(list->v1, tmp, sizeof(tmp_data) * list->num); // 仅释放tmp中未被转移的p1(索引5到9) for(i=5;i<10;i++) { free(tmp[i].p1); } }
此时list->v1[i].p1直接接管tmp[i].p1的内存,main函数中释放这些指针是安全的,无double free或内存泄漏问题。
方案2:深层复制(保留list的独立内存)
若希望list拥有完全独立的内存空间,不依赖tmp的指针,需逐个复制结构体字段,避免覆盖list->v1[i].p1的指针:
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(list->num, sizeof(tmp_data)); // 逐个复制字段,避免覆盖p1指针 for(i=0;i<list->num;i++) { // 为list的p1分配独立内存 list->v1[i].p1 = calloc(1, sizeof(tmp_type)); // 复制tmp_type的内容 memcpy(list->v1[i].p1, tmp[i].p1, sizeof(tmp_type)); // 复制char类型的a字段 list->v1[i].a = tmp[i].a; // 释放tmp的p1,内容已完成复制 free(tmp[i].p1); } // 释放tmp中剩余未使用的p1 for(i=5;i<10;i++) { free(tmp[i].p1); } }
这里去掉了错误的批量memcpy操作,改为逐个复制结构体的每个字段,确保list->v1[i].p1指向自身分配的内存。复制完成后释放tmp的p1,main函数中释放list的p1不会引发问题,也无内存泄漏。
内容的提问来源于stack exchange,提问作者LostProgrammer
相关产品推荐
相关产品推荐

