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

从std::set提取含unique_ptr成员的结构体触发UAF错误如何解决

问题根源

触发错误的核心原因是std::set::extract的返回值使用方式错误:
extract方法返回的是临时节点句柄对象,该对象持有从set中取出的struct A实例的所有权。你直接对临时节点句柄调用.value()取引用,没有保存节点句柄本身,当前语句执行结束后临时节点句柄会立即被析构,它持有的struct A实例也会跟着销毁,实例内的std::unique_ptr自然会释放指向的堆内存,你后续访问的element引用已经是悬垂引用,就触发了AddressSanitizer的堆释放后使用报错。
你贴的ASAN日志中标记的[fd]阴影位对应「已释放的堆区域」,和问题现象完全匹配。

修复方案

有两种常用修复方式:

  • 方案1:保存extract返回的节点句柄局部变量,再访问内部元素
    如果后续修改完元素还需要放回原set/插入其他set,推荐用该方案:
struct A {
    std::unique_ptr<int> weight;
};

// 先保存节点句柄,生命周期和局部变量绑定,内部元素不会提前销毁
auto node = set_.extract(set_iterator);
auto& element = node.value();
std::cout << *(element.weight);

// 元素修改完成后可以插回set
// set_.insert(std::move(node));
  • 方案2:直接移动取出元素
    如果不需要保留节点句柄,直接把元素从临时节点里移动出来即可:
A element = std::move(set_.extract(set_iterator).value());
std::cout << *(element.weight);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 19:51:02