重载 new 和删除 C++用于跟踪内存分配

发布于 2024-10-21 00:28:44 字数 1338 浏览 3 评论 0原文

我需要帮助来理解下面截取的代码...allocate 是一个由重载的 new 运算符调用来分配内存的函数。我在尝试理解以下强制转换时遇到问题:

*static_cast<std::size_t*>(mem) = pAmount; //please explain?

return static_cast<char*>(mem) + sizeof(std::size_t); //? 

并且..

// get original block
void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t); //?

代码如下所示:

const std::size_t allocation_limit = 1073741824; // 1G
    std::size_t totalAllocation = 0;

    void* allocate(std::size_t pAmount)
    {
        // make sure we're within bounds
        assert(totalAllocation + pAmount < allocation_limit);

        // over allocate to store size
        void* mem = std::malloc(pAmount + sizeof(std::size_t));
        if (!mem)
            return 0;

        // track amount, return remainder
        totalAllocation += pAmount;
        *static_cast<std::size_t*>(mem) = pAmount;

        return static_cast<char*>(mem) + sizeof(std::size_t);
    }

    void deallocate(void* pMemory)
    {
        // get original block
        void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);

        // track amount
        std::size_t amount = *static_cast<std::size_t*>(mem);
        totalAllocation -= pAmount;

        // free
        std::free(mem);
    }

I need help in understanding the code snipped below...allocate is a function that would be called by the overloaded new operator to allocate memory. I am having problems trying to understand the following casts in particular:

*static_cast<std::size_t*>(mem) = pAmount; //please explain?

return static_cast<char*>(mem) + sizeof(std::size_t); //? 

and..

// get original block
void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t); //?

the code is shown below:

const std::size_t allocation_limit = 1073741824; // 1G
    std::size_t totalAllocation = 0;

    void* allocate(std::size_t pAmount)
    {
        // make sure we're within bounds
        assert(totalAllocation + pAmount < allocation_limit);

        // over allocate to store size
        void* mem = std::malloc(pAmount + sizeof(std::size_t));
        if (!mem)
            return 0;

        // track amount, return remainder
        totalAllocation += pAmount;
        *static_cast<std::size_t*>(mem) = pAmount;

        return static_cast<char*>(mem) + sizeof(std::size_t);
    }

    void deallocate(void* pMemory)
    {
        // get original block
        void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);

        // track amount
        std::size_t amount = *static_cast<std::size_t*>(mem);
        totalAllocation -= pAmount;

        // free
        std::free(mem);
    }

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

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

发布评论

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

评论(4

卷耳 2024-10-28 00:28:44

分配器通过将分配的大小与其提供给客户端代码的块一起保存来跟踪分配的大小。当请求 pAmount 字节块时,它会在开头分配一个额外的 sizeof(size_t) 字节并将大小存储在那里。为了达到这个大小,它将从 malloc 获取的 mem 指针解释为 size_t* 并取消引用 (*static_cast) std::size_t*>(mem) = pAmount;)。然后它返回块的其余部分,从 mem + sizeof(size_t) 开始,因为这是客户端可以使用的部分。

释放时,它必须将从 malloc 获得的确切指针传递给 free。为了获取此指针,它减去在 allocate 成员函数中添加的 sizeof(size_t) 字节。

在这两种情况下,都需要强制转换为 char*,因为 void 指针上不允许进行指针算术。

The allocator keeps track of the size of allocations by keeping them along with the blocks it serves to client code. When asked for a block of pAmount bytes, it allocates an extra sizeof(size_t) bytes at the beginning and stores the size there. To get to this size, it interprets the mem pointer it gets from malloc as a size_t* and dereferences that (*static_cast<std::size_t*>(mem) = pAmount;). It then returns the rest of the block, which starts at mem + sizeof(size_t), since that is the part that the client may use.

When deallocating, it must pass the exact pointer it got from malloc to free. To get this pointer, it subtracts the sizeof(size_t) bytes it added in the allocate member function.

In both cases, the casts to char* are needed because pointer arithmetic is not allowed on void pointers.

扎心 2024-10-28 00:28:44

void* allocate(std::size_t pAmount)

分配 pAmount 内存加上存储大小的空间

|-size-|---- pAmount of memory-----|

   ^
   |

“分配”将返回刚刚粘贴大小字段的指针。

void deallocate(void* pMemory)

会将指针移回到开头

|-size-|---- pAmount of memory-----|

^
|

并释放它。

1.)

std::size_t mySize = 0;

void * men = & mySize;

// same as: mySize = 42;
*static_cast<std::size_t*>(mem) = 42;

std::cout << mySize;
// prints "42"

2.)

`return static_cast<char*>(mem) + sizeof(std::size_t);
// casts void pointer mem to a char* so that you can do pointer arithmetic.
// same as

char *myPointer = (char*)mem;

// increment myPointer by the size of size_t
return myPointer + sizeof(std::size_t);

3.)

`void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);`
// mem points size of size_t before pMemory

void* allocate(std::size_t pAmount)

allocates pAmount of memory plus space to store the size

|-size-|---- pAmount of memory-----|

   ^
   |

"allocate" will return a pointer just pasted the size field.

void deallocate(void* pMemory)

will move the pointer back to the beginning

|-size-|---- pAmount of memory-----|

^
|

and free it.

1.)

std::size_t mySize = 0;

void * men = & mySize;

// same as: mySize = 42;
*static_cast<std::size_t*>(mem) = 42;

std::cout << mySize;
// prints "42"

2.)

`return static_cast<char*>(mem) + sizeof(std::size_t);
// casts void pointer mem to a char* so that you can do pointer arithmetic.
// same as

char *myPointer = (char*)mem;

// increment myPointer by the size of size_t
return myPointer + sizeof(std::size_t);

3.)

`void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);`
// mem points size of size_t before pMemory
月野兔 2024-10-28 00:28:44

为了知道删除内存时要清理多少内存(并提供一些诊断),分配器将大小存储在额外分配的内存中。

*static_cast(mem) = pAmount; //请解释一下?

这将获取分配的内存并将分配的字节数存储到该位置。出于存储目的,转换将原始内存视为 size_t

返回 static_cast(mem) +
sizeof(std::size_t); //?

这将向前移动超过 size 字节到应用程序将使用的实际内存并返回该指针。

无效*内存=
static_cast(pMemory) -
sizeof(std::size_t); //?

这是将之前返回给用户的块前进回之前存储大小的“真实”分配块。需要进行检查并回收内存。

In order to know how much memory to clean up when you delete it (and provide some diagnostics) the allocator stores off the size in extra allocated memory.

*static_cast(mem) = pAmount; //please explain?

This takes the allocated memory and stores the number of allocated bytes into this location. The cast treats the raw memory as a size_t for storage purposes.

return static_cast(mem) +
sizeof(std::size_t); //?

This moves forward past the size bytes to the actual memory that your application will use and returns that pointer.

void* mem =
static_cast(pMemory) -
sizeof(std::size_t); //?

This is taking the block previously returned to the user and advancing back to the "real" allocated block that stored the size earlier. It's needed to do checks and reclaim the memory.

野味少女 2024-10-28 00:28:44

由于 void* 不是具有大小的类型,因此需要进行强制转换才能获得正确的偏移量。

当你写

return static_cast(mem) + sizeof(std::size_t);

时在添加偏移字节之前,指针被转换为 char*。

解除分配时同上减去。

the cast is needed in order to get the proper offset since void* is not a type with a size.

when you write

return static_cast(mem) + sizeof(std::size_t);

the pointer is cast to a char* before the offset bytes is added.

ditto subtract when deallocating.

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