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

为何这段Windows API代码会引发堆损坏?

代码问题排查:VS2019启用AddressSanitizer时堆损坏异常

这段代码用于为单个文件调用多文件属性对话框。在Visual Studio 2019中启用地址 sanitizer(/fsanitize=address)编译时,会在系统DLL的MessageBoxW(...)行触发堆损坏异常:

未处理的异常在0x77BCC97F (ntdll.dll)处(ConsoleApplication2.exe中):0xC0000374: 堆已损坏(参数: 0x77C0A918)。

禁用sanitizer编译或使用VS2022编译时无此错误。

#include <windows.h>
#include <Shlobj.h>

int main()
{
    CoInitialize(nullptr);
    IShellFolder* pDesktop; // namespace root for parsing the path
    HRESULT hr = SHGetDesktopFolder(&pDesktop);

    if (!SUCCEEDED(hr)) {
        return 0;
    }

    HWND m_hWnd = {};
    LPCWSTR fileName = L"c:\\Windows\\notepad.exe";
    LPWSTR fileNameDup = _wcsdup(fileName);

    LPITEMIDLIST newPIdL;

    IDataObject* pDataObject = {};
    hr = pDesktop->ParseDisplayName(m_hWnd, nullptr, fileNameDup, nullptr, &newPIdL, nullptr);
    if (SUCCEEDED(hr)) {
        LPCITEMIDLIST list[] = { newPIdL };
        hr = pDesktop->GetUIObjectOf(m_hWnd, 1, list, IID_IDataObject, nullptr, reinterpret_cast<void**>(&pDataObject));

        if (SUCCEEDED(hr)) {

            hr = SHMultiFileProperties(pDataObject, 0);

            if (SUCCEEDED(hr)) {
                MessageBoxW(nullptr, L"Test", L"Test", 0);
            }
            pDataObject->Release();
        }
        CoTaskMemFree(newPIdL);
    }

    pDesktop->Release();
    free(fileNameDup);
    
    CoUninitialize();
    return 0;
}

代码本身的问题检查

从逻辑上看,这段代码没有明显错误:

  • COM初始化与反初始化流程规范
  • Shell接口对象的Release调用、内存释放(CoTaskMemFree对应ParseDisplayName的返回值,free对应_wcsdup的分配)都匹配了正确的分配方式
  • SHMultiFileProperties的调用参数符合要求,IDataObject的获取与释放也没有遗漏

可能的错误原因

  • VS2019 AddressSanitizer兼容性缺陷:旧版本的ASan和系统Shell组件(尤其是SHMultiFileProperties涉及的对话框相关DLL)存在兼容性bug,VS2022对ASan做了更新修复,因此不会触发该问题。
  • 堆管理机制冲突:ASan会替换程序默认的堆分配器,而系统Shell的某些内部操作可能使用了未被ASan正确拦截的堆操作,导致堆状态被破坏,后续MessageBoxW调用时触发堆损坏检测。
  • ParseDisplayName的指针修改误判:IShellFolder::ParseDisplayName会修改传入的字符串指针(移动到解析完成后的位置),虽然代码中未使用修改后的指针,但ASan可能对这种指针变动场景存在误判。可以尝试改用SHParseDisplayName替代IShellFolder::ParseDisplayName,看是否能规避问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:45:29