这是一个廉价的黑客,但我正在尝试更改我正在处理的C库的分配方法。出于某种原因,它使用了GlobalLock,可能是因为它曾经是多个DLL。我已将其更改为alloc:
HANDLE BmiDibAlloc(size_t uBytes)
{
HANDLE alloc = malloc(uBytes + sizeof (size_t));
if (alloc != NULL)
{
memcpy_s(alloc, sizeof (alloc), &uBytes, sizeof (size_t));
}
return BmiDibAttach(alloc); //just tracks the number of memory allocs for logging
}
BOOL BmiDibFree(HANDLE hdib)
{
if (!hdib) {
return TRUE;
}
free(hdib);
// Forget this handle:
return BmiDibDetach(hdib);
}
由于我不能再使用GlobalSize了,我在第一个sizeof(size_t)字节上调整了分配的大小......
当使用第一种方法分配后位图写入正常时 - 但是,当我转到Free时会引发堆损坏。当然,它可能介于这些调用之间,是否有人通过给出的信息看到了错误?
答案 0 :(得分:2)
分配块时,分配更多空间,将标头存储在块的开头,然后返回指向块内偏移量的指针(不是块的开头)。例如“return alloc + sizeof(MY_HEADER)”。
当你释放一个区块时,你必须反过来。例如:
BOOL BmiDibFree(HANDLE callerPointer)
{
actualPointer = callerPointer - sizeof(MY_HEADER);
free(actualPointer);
注1:为了提高性能,你应该确保“sizeof(MY_HEADER)”是“malloc()”提供的最小对齐的倍数;所以你不会给调用者造成错位问题。
注意2:您可以在块的实际开始处和块的实际末尾添加“canaries”(幻数),并检查这些(在free和realloc期间)以增加检测堆损坏的机会。我这样做并设置了“heap was corrupted”标志,并在任何malloc / free / realloc之前测试此标志(如果堆已损坏,所有后续操作立即失败以避免使混乱变大)。
注3:您可以使用条件编译(例如“#ifdef DEBUGGING”)来启用/禁用包装器的各种功能。我这样做 - 一个用于启用额外检查(金丝雀),一个用于启用统计信息的收集/报告(分配的块总数,最大分配的块数,分配的总字节数,最大数量任何时候分配的字节数。)
答案 1 :(得分:0)