gpt4 book ai didi

c# - CoTaskMemAlloc v malloc v AllocHGlobal

转载 作者:行者123 更新时间:2023-11-30 20:20:31 36 4
gpt4 key购买 nike

我读过,在 Windows 上,malloc 不同于 CoTaskMemAlloc,后者又不同于 AllocHGlobal。对于 C# 使用者,这可能意味着如果我有一个返回 malloc 指针的 C 函数,我需要对其调用 free。如果我 P/Invoke 并指定一个字符串返回类型,CLR 应该调用 CoTaskMemFree 并且应该在 malloc 指针上失败。

但是,我无法在实践中看到这一点。我创建了一个 DLL,它只返回一个 malloc'd char* 并将其作为字符串 P/Invoked。没有内存泄漏。事实上,无论我尝试什么,我都不能让事情失败。我调用 malloc、GlobalHAlloc、CoTaskMemAlloc,然后使用任何免费的实现,一切正常。没有内存泄漏。重复使用相同的内存空间。

我怎样才能强制它失败?或者这是应该是“实现定义”但实际上只是以一种方式工作的事情之一?

这是在 VS2015 更新 2,Windows 8.1 上。

最佳答案

这肯定没用过。但事情一直在变化。 C 运行时库 was changed in VS2012它不再创建自己的堆。对于 VS2015,C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\heap\heap_handle.cpp 中的这段代码是相关的:

// Initializes the heap.  This function must be called during CRT startup, and
// must be called before any user code that might use the heap is executed.
extern "C" bool __cdecl __acrt_initialize_heap()
{
__acrt_heap = GetProcessHeap();
if (__acrt_heap == nullptr)
return false;

return true;
}

注意对 GetProcessHeap() 的调用,它返回 Marshal.AllocHGlobal() 从中分配的同一个堆。所以是的,当您使用 Marshal.FreeHGlobal() 取消分配时,您不会从调试堆中获得异常或泄漏。

CoTaskMemAlloc() 也差不多。单步执行函数,我看到:

7638D1E1  mov         esi,dword ptr [g_CMalloc (76485EE0h)]  
7638D1E7 push dword ptr [ebp+8]
7638D1EA mov esi,dword ptr [esi+0Ch]
7638D1ED cmp esi,offset CRetailMalloc_Alloc (763732C0h)
7638D1F3 jne CoTaskMemAlloc+44h (7638D214h)
7638D1F5 push 0
7638D1F7 push dword ptr [g_hHeap (76485E68h)]
7638D1FD call dword ptr [__imp__HeapAlloc@12 (76488228h)]

注意 g_hHeap 变量的用法。我看到它与 GetProcessHeap() 返回的值相同。因此,再次声明,释放任何释放函数都可以正常工作。

请注意,这是我从 Windows 10 获得的,旧版本的 Windows 不会以相同的方式运行。并注意 CRetailMalloc_Alloc,这是一个不太令人愉快的随机化器,其用法不可预测。

虽然这当然是有帮助的,但程序失败的方式要少得多,但在您测试应用程序时它实际上并没有用。真的很讨厌,它调用了“只在我的机器上工作”的故障模式。呸。

关于c# - CoTaskMemAlloc v malloc v AllocHGlobal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36420692/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com