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

多线程下重复释放对象未触发double free检测的原因探究

多线程下重复释放指针未被检测的原因分析

单线程测试场景

单线程代码示例:

class A {};

A* a = new A;

int main()
{
   delete a;
   delete a;
   return 0;
}

执行后控制台明确输出重复释放的错误:

free(): double free detected in tcache 2

这个结果符合内存分配器的保护机制预期。

多线程测试场景

多线程代码示例:

class A {};

A* a = new A;


void func()
{
   std::this_thread::sleep_for(std::chrono::seconds(3));
   delete a;
}

int main()
{
   std::thread t{ func };

   delete a;

   t.join();

   return 0;
}

执行这段代码后,并未触发重复释放的检测提示,原因主要有以下几点:

  • 内存分配器的检测逻辑限制:单线程中连续两次释放同一个指针时,内存分配器(比如glibc的tcache)会立刻识别——刚释放的内存块还在当前线程的缓存链表中,二次释放操作会直接触发校验报错。但多线程场景下,主线程先释放指针后,这块内存可能在子线程执行释放的3秒间隔内,被分配器重新回收、甚至复用给其他隐性操作,此时分配器无法识别这是同一指针的二次释放。

  • 未定义行为的随机性:C++标准中,重复释放指针属于未定义行为——语言本身不保证一定会触发错误提示,单线程中的报错只是分配器提供的额外保护机制,不是强制要求。多线程环境下,未定义行为的表现更不可预测,可能静默执行、可能崩溃、也可能像这样不触发检测。

  • 线程本地缓存的隔离性:以glibc的tcache为例,它是线程独有的内存缓存。主线程释放指针后,内存块会进入主线程的本地缓存;子线程执行释放时,它的本地缓存中没有该块的记录,分配器会直接将其归还给全局堆,不会触发跨线程的重复释放校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:50:26