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

关于std::unique_ptr自动释放内存的疑问:Windows消息传递场景下的对象释放问题

关于std::unique_ptr自动释放内存的疑问:Windows消息传递场景下的对象释放问题

嘿,这个场景我熟,直接给你结论:只要你在消息处理函数里正确用std::unique_ptr接管了那个new出来的对象,当处理函数返回时,这个对象肯定会被自动释放。

咱们一步步拆解整个流程,你就明白为啥了:

  • 首先你用new BackupStatusMsg{...}在堆上分配了对象,然后通过PostMessage把地址发出去——这里要记得PostMessage是异步的,发完就返回,不会等消息被处理。
  • 当窗口的消息队列轮到处理WM_BACKUP_STATUS时,你的DialogClass::OnBackupStatus(应该是你打错成OnSo了吧😉)函数会被调用,你把LPARAM转成原始指针,用它初始化std::unique_ptr。这一步非常关键:从这一刻起,std::unique_ptr就完全接管了这个堆对象的所有权,原始指针就不该再被用来操作这个对象了。
  • 当消息处理函数执行完毕,函数里的std::unique_ptr局部变量会离开它的作用域,这时候std::unique_ptr的析构函数会自动触发,调用delete释放它管理的那个BackupStatusMsg对象,内存就被正确回收了。

给你把代码补全更清楚:
发送消息的代码:

auto* data = new BackupStatusMsg{ pct, st, e1, e2, msg };
::PostMessage(m_hWnd, WM_BACKUP_STATUS, 0, reinterpret_cast<LPARAM>(data));

消息处理函数里的代码(假设你是这么写的):

LRESULT DialogClass::OnBackupStatus(WPARAM wParam, LPARAM lParam)
{
    // 把LPARAM转回原始指针,用它初始化unique_ptr
    std::unique_ptr<BackupStatusMsg> msgData(reinterpret_cast<BackupStatusMsg*>(lParam));
    
    // 这里用msgData做你要的操作,比如访问它的成员
    // ...

    // 函数返回时,msgData离开作用域,自动调用delete释放对象
    return 0;
}

不过有两个坑得提前踩住:

  • 绝对不能让其他智能指针或者原始指针再去释放这个对象,不然会触发**重复释放(double free)**的崩溃——毕竟unique_ptr的核心就是独占所有权。
  • 要确保窗口在消息被处理前不会被销毁!如果窗口提前关了,PostMessage的消息可能会被系统丢弃,那你new出来的对象就没人接管了,直接内存泄漏。这种情况你可以先判断PostMessage的返回值,如果返回0说明消息没发出去,这时候要手动delete那个data,避免泄漏。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:53:04