You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言调用free触发double free或corruption错误的问题排查

问题原因排查

核心根因

内存分配时的类型大小计算错误,导致堆内存越界写入,破坏了malloc/free维护的堆元数据,是触发free报错的核心原因。

具体错误点

在init_and_set_v1函数中,你为foo1类型的数组分配内存时,错误使用了foo2的大小计算:

// 错误写法:用了foo2的大小计算foo1数组的内存需求
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );

myfoo1s是指向foo1结构体数组的指针,应该按foo1的大小分配内存,推荐两种修正写法:

// 写法1:直接指定foo1类型
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo1) );
// 写法2:用指针指向的类型计算,避免写错类型名,适配后续类型变更
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(*((*myfoo2)->myfoo1s)) );

错误触发原理

64位系统下foo1的大小是3个double共24字节,foo2对齐后的大小是16字节。你申请10个元素的数组时,错误写法仅分配了160字节,实际需要240字节,后续给v2、v3赋值时,写入范围超过了申请的内存边界,直接覆盖了堆上紧邻的、用来记录内存块大小/空闲状态的元数据,调用free时系统校验元数据发现被篡改,就会抛出corrupted size vs. prev_size、信号6的错误。

额外注意事项

  • 不要在注释标注的location1、location2位置释放myfoo1s,这两个位置释放后,后续代码还会访问已释放的内存,会触发野指针访问错误,仅需在所有逻辑都使用完myfoo1s的location3位置释放即可
  • 代码还漏了myfoo2本身的释放,用完后要先free(myfoo2->myfoo1s),再free(myfoo2),避免内存泄漏
  • 排查这类内存问题时,编译可添加-g -Wall -fsanitize=address参数,GCC的地址消毒工具会直接定位到越界写入的位置,大幅提升排查效率

内容的提问来源于stack exchange,提问作者ahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:18:05