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

如何将CreateDIBSection返回的BYTE*转为unique_ptr?出现段错误

问题分析与解决

错误原因

你遇到的段错误核心是内存所有权管理逻辑错误:

  • CreateDIBSection分配的像素缓冲区,所有权属于返回的HBITMAP对象,而非用户手动管控的内存。系统会在你调用DeleteObject(hBitmap2)销毁位图时自动释放这块内存,绝对不能用delete或delete[]手动释放。
  • 你使用的std::unique_ptr(包括数组版)默认删除器会调用delete/delete[],这违反了WinAPI GDI的内存管理规则。当unique_ptr生命周期结束时,会非法尝试释放这块内存,导致内存损坏,进而引发访问段错误。

正确处理方式

方式一:直接管理HBITMAP,不单独管控像素指针

这是最贴合WinAPI设计的常规做法:

  1. 用裸指针接收CreateDIBSection返回的像素地址,正常访问操作数据。
  2. 在不再使用位图时,调用DeleteObject(hBitmap2),系统会自动释放像素缓冲区。

示例代码:

BYTE* bitPointer = nullptr;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, reinterpret_cast<void**>(&bitPointer), NULL, NULL);

// 正常遍历访问像素数据
for (int i = 0; i < 1080*1920*4; ++i) {
    // 操作 bitPointer[i]
}

// 不再使用时销毁位图,像素内存自动释放
if (hBitmap2) {
    DeleteObject(hBitmap2);
}

方式二:用智能指针管理HBITMAP(推荐)

如果想利用智能指针自动管控资源,避免手动销毁遗漏,可以给HBITMAP绑定自定义删除器:

// 定义HBITMAP的自定义删除器
struct HBitmapDeleter {
    void operator()(HBITMAP hbmp) const {
        if (hbmp) DeleteObject(hbmp);
    }
};

// 封装带自定义删除器的unique_ptr
using UniqueHBITMAP = std::unique_ptr<std::remove_pointer_t<HBITMAP>, HBitmapDeleter>;

BYTE* bitPointer = nullptr;
BITMAPINFO bitmap = { /* 你的BITMAPINFO初始化代码 */ };

UniqueHBITMAP hBitmapSmartPtr(CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, reinterpret_cast<void**>(&bitPointer), NULL, NULL));

// 正常访问bitPointer操作像素数据
// 当hBitmapSmartPtr离开作用域时,自动调用DeleteObject销毁位图,释放像素内存

关于你的疑问

你认为“调用CreateDIBSection()只能使用裸指针变量”是正确的——该函数需要通过裸指针输出像素缓冲区地址,无法直接传入智能指针的内部指针,必须先用裸指针接收,再按上述方式管控资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:52:50