更新 C 库,导致堆损坏

发布于 2024-12-27 22:08:07 字数 708 浏览 3 评论 0原文

这是一个廉价的 hack,但我正在尝试更改我正在开发的 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) 字节上添加了分配的大小...

当使用第一种方法分配后位图写入正常时 - 但是,当我到达释放它会引发堆损坏。假设它可能介于这些调用之间,那么有人认为所提供的信息有问题吗?

This is a cheap hack but I am trying to change the allocation method of a C library I am working on. For some reason it used GlobalLock, perhaps because it used to be multiple DLLs. I have changed it to 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);
}

Since I cannot use GlobalSize anymore I tack on the size of the allocation on the first sizeof (size_t) bytes...

When The bitmap writes fine after allocated with the first method - however, when I get to Free it throws a heap corruption. Granted it may be somewhere inbetween these calls, does anyone see something wrong with this with the information given?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人海汹涌 2025-01-03 22:08:07

当您分配一个块时,您会分配更多的空间,将标头存储在块的开头,然后返回指向块内偏移量的指针(而不是块的开头)。例如“返回 alloc + sizeof(MY_HEADER)”。

当你释放一个块时,你必须执行相反的操作。例如:

BOOL BmiDibFree(HANDLE callerPointer)
{
    actualPointer = callerPointer - sizeof(MY_HEADER);
    free(actualPointer);

注1:为了性能,应确保“sizeof(MY_HEADER)”是“malloc()”提供的最小对齐方式的倍数;这样就不会给调用者造成错位问题。

注2:您可以在块的实际开始处和块的实际结束处添加“金丝雀”(幻数),并检查这些(在 free 和 realloc 期间)以增加检测堆损坏的机会。我这样做并设置一个“堆已损坏”标志,并在任何 malloc/free/realloc 之前测试此标志(如果堆已损坏,所有后续操作都会立即失败,以避免使混乱变得更大)。

注3:您可以使用条件编译(例如“#ifdef DEBUGGING”)来启用/禁用包装器的各种功能。我也这样做 - 一种是启用额外检查(金丝雀),另一种是启用统计信息的收集/报告(分配的块总数、任何时间分配的最大块数、分配的字节总数、最大数量)任何时间分配的字节数)。

When you allocate a block, you allocate a little more space, store your header at the beginning of the block, then return a pointer to an offset within the block (not the start of the block). For example "return alloc + sizeof(MY_HEADER)".

When you free a block you have to do the reverse. For example:

BOOL BmiDibFree(HANDLE callerPointer)
{
    actualPointer = callerPointer - sizeof(MY_HEADER);
    free(actualPointer);

Note 1: For performance, you should make sure that "sizeof(MY_HEADER)" is a multiple of the minimum alignment provided by "malloc()"; so you don't cause mis-alignment problems for the caller.

Note 2: You can add "canaries" (magic numbers) at the real start of the block and at the real end of the block, and check these (during free and realloc) to increase the chance of detecting heap corruption. I do this and set a "heap was corrupted" flag, and test this flag before any malloc/free/realloc (if the heap was corrupted, all subsequent operations fail immediately to avoid making the mess larger).

Note 3: You can use conditional compiling (e.g. "#ifdef DEBUGGING") to enable/disable various features of your wrapper. I do this too - one to enable extra checking (the canaries) and one to enable the gathering/reporting of statistics (total number of blocks allocated, max. number of blocks allocated at any time, total number of bytes allocated, max. number of bytes allocated at any time).

人间☆小暴躁 2025-01-03 22:08:07

问:你的意思是“sizeof(size_t)”吗?这通常只有 4 个字节。与“sizeof(alloc)”相同 - 它可能只是“4”。

Q: Do you really mean "sizeof (size_t)"? This is typically just 4 bytes. The same with "sizeof(alloc)" - it's probably just "4".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文