我有一个 ETW 提供程序,但 Visual Studio 调试 CRT 报告其中存在内存泄漏。注册事件的调用会在堆上创建一个 wchar_t*:
auto msg = convertToWchar(string); // calls new wchar_t[]
EventWriteBegin (msg);
EventWriteBegin() 函数是 ETW 编译器生成的 Template_xyz() 函数中的宏:
ULONG
Template_xyz(
_In_ REGHANDLE RegHandle,
_In_ PCEVENT_DESCRIPTOR Descriptor,
_In_opt_ PCWSTR _Arg0)
{
#define ARGUMENT_COUNT_zdf 1
EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zdf];
EventDataDescCreate(&EventData[0],
(_Arg0 != NULL) ? _Arg0 : L"NULL",
(_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zdf, EventData);
}
我的问题是:我是否可以假设在将 PCWSTR 参数传递给 EventDataDescCreate 并调用 EventWrite() 后,可以释放我传递给它的字符串吗?
EventDataDescCreate() 和 EventWrite() 的文档没有提及参数的生命周期语义。
当 Windows 获得所有权时,它会告诉您如何释放该内存。通常是
GlobalFree
或 CoTaskMemFree
,而不是 delete[]
。这显然意味着您需要相应的分配器而不是new wchar_t[]
。在这里,没有所有权转移,所以 new[]/delete[]
没问题。
“在堆上分配”在这种情况下会令人困惑,因为它可以被解释为操作系统函数
HeapAlloc
,而不是new[]