【问题标题】:How to allocate a void* array on the heap?如何在堆上分配一个 void* 数组?
【发布时间】:2017-12-04 03:10:55
【问题描述】:

我想使用 windows api 调用GetWriteWatch()。此方法采用我在堆栈上分配的void* 数组,如下所示:void* lpAddresses[PAGE_COUNT]; 现在的问题是,PAGE_COUNT 需要很大,这会导致堆栈溢出。 我如何写这个来分配堆上的内存? 我试过了:

void* lpAddresses = ::operator new[](PAGE_COUNT); 
void* lpAddresses = ::operator new(PAGE_COUNT); 
void* lpAddresses = malloc(PAGE_COUNT*sizeof(void*));

但这会导致来自GetWriteWatch()的错误代码

有效的堆栈版本:

ULONG_PTR lpdwCount = PAGE_COUNT;
void *lpAddresses[PAGE_COUNT];
ULONG lpdwGranularity;
UINT result = GetWriteWatch(WRITE_WATCH_FLAG_RESET, m_rawMemory.as_void, m_alloc_size, lpAddresses, &lpdwCount, &lpdwGranularity);

谢谢

【问题讨论】:

  • 在堆上分配数组后如何调用GetWriteWatch?为什么不包含在问题中?
  • void* lpAddresses[PAGE_COUNT] 是一个 void* 指针数组。 new[] 等效于 void** lpAddresses = new void*[PAGE_COUNT];,或者更好的是 std::vector<void*> lpAddresses(PAGE_COUNT);
  • GetWriteWatch 的结果!= 0。是的,我用 & then 传递了它。还是没有运气。
  • 不,不,不!我的错。如果您使用malloc 版本,则必须通过(PVOID *) lpAddresses。不是&lpAddresses。传递&lpAddresses 是绝对错误的。
  • @RemyLebeau 如果您可以将其发布为答案,我将接受此作为答案。谢谢你。两个版本都可以。

标签: c++ winapi memory-management allocation


【解决方案1】:

当你使用这个函数时,你必须使用windows函数VirtualAlloc()使用标志MEM_WRITE_WATCH分配内存

类似这样的:

lpAddress = VirtualAlloc(NULL, PAGE_COUNT, MEM_WRITE_WATCH, PAGE_READWRITE);

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366573(v=vs.85).aspx

【讨论】:

  • 为什么??? MEM_WRITE_WATCH 用于查看内存页面。它与这个数组内存的分配完全无关。这就是您的链接页面所说的。
  • 谢谢,但这与受监控的内存无关。我想堆分配数组以传递和接收页面地址,这样我的堆栈就不会死。
  • 他已经说过堆栈内存工作正常。所以解决办法不可能是他需要VirtualAlloc吧???
  • @AnT - 也许你应该阅读链接页面。它说:“此地址必须位于由 VirtualAlloc 函数使用 MEM_WRITE_WATCH 分配的内存区域中。”
  • @bennji_of_the_overflow:不,是你必须更仔细地阅读它。你引用的那句话适用于lpBaseAddress,而不是lpAddresses。正是我在上面的评论中所说的。这个问题是关于为lpAddresses分配内存的。
【解决方案2】:

malloc 版本中的内存分配本身是完全正确的。 (::operator new 版本不正确。)请记住,为了传递初始化如下的指针

void* lpAddresses = malloc(PAGE_COUNT*sizeof(void*));
// Assuming `void *` is synonymous with `PVOID`

GetWriteWatch,您必须将指针转换为正确的类型,即您必须传递(PVOID *) lpAddresses。改为传递 &lpAddresses(根据 cmets 的说法,这是您所做的)是完全不正确的。

如果我决定在这种情况下使用malloc,我的做法会略有不同

PVOID *lpAddresses = (PVOID *) malloc(PAGE_COUNT * sizeof *lpAddresses);

即我会在分配内存时执行强制转换,然后将普通的 lpAddresses 传递给 GetWriteWatch

你也可以使用

PVOID *lpAddresses = new PVOID[PAGE_COUNT];

在这种情况下,您会将纯 lpAddresses 传递给函数。

您还可以使用std::vector 或任何其他内存分配机制。只需继续观察正确的间接级别即可。

【讨论】:

    猜你喜欢
    • 2015-07-26
    • 2013-09-28
    • 1970-01-01
    • 2020-01-05
    • 2019-01-09
    • 2020-10-26
    • 2015-12-22
    • 2021-03-14
    相关资源
    最近更新 更多