使用运算符new和运算符delete与自定义内存池/分配器 [英] Using operator new and operator delete with a custom memory pool/allocator

查看:181
本文介绍了使用运算符new和运算符delete与自定义内存池/分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理内存池/内存分配器实现,我设置在一个庄园,只有一个特殊的客户端对象类型可以从池中绘制。客户端可以直接构建到池,或者它可以使用池用于动态内存调用,或者它可以在理论上同时使用。
我希望能够重载运算符新运算符删除,这样就可以调用我的池alloc()和free()函数,以便获得构建对象所需的内存。

I'm working on a memory pool/memory allocator implementation and I am setting it up in a manor where only a special "Client" object type can draw from the pool.The client can either be constructed directly onto the pool, or it can use the pool for dynamic memory calls or it could in theory do both. I would like to be able to overload operator new and operator delete in a way that would call my pools "alloc()" and "free()" functions in order to get the memory needed for the object to construct upon.

我遇到的主要问题之一是让我的操作员删除,以便能够通过调用pool-> free()函数释放内存。我想出了一个黑客,通过将池传递到构造函数并让析构函数做解除分配工作来修复它。这是所有罚款和dandy,直到有人需要继承这个类,并重写析构函数为自己的需求,然后忘记做内存释放。这是为什么我想包装它所有的运算符,所以功能是折叠和默认继承。

One of the main issues that I am having is getting my operator delete to be able to free up the memory by calling the pool->free() function I have written. I came up with a hack that fixes it by passing the pool into the constructor and having the destructor do the deallocation work. This is all fine and dandy until someone needs to inherit from this class and override the destructor for their own needs and then forgets to do the memory deallocations. Which is why i want to wrap it all up in the operators so the functionality is tucked away and inherited by default.

我的代码在GitHub在这里: https://github.com/zyvitski/Pool

My Code Is on GitHub here: https://github.com/zyvitski/Pool

我的客户的类定义如下:

My class definition for the Client is as follows:

class Client
{
public:
    Client();
    Client(Pool* pool);
    ~Client();

    void* operator new(size_t size,Pool* pool);
    void operator delete(void* memory);

    Pool* m_pPool;
};

其实现是:

Client::Client()
{

}
Client::Client(Pool* pool)
{
    m_pPool = pool;
}
Client::~Client()
{
    void* p = (void*)this;
    m_pPool->Free(&p);
    m_pPool=nullptr;
}
void* Client::operator new(size_t size, Pool* pool)
{
    if (pool!=nullptr) {
        //use pool allocator
        MemoryBlock** memory=nullptr;
        memory = pool->Alloc(size);
       return *memory;
    }
    else throw new std::bad_alloc;
}
void Client::operator delete(void* memory)
{
    //should somehow free up the memory back to the pool
    // the proper call will be:
    //pool->free(memory);
    //where memory is the address that the pool returned in operator new

}


b $ b

这里是我现在使用的Main()例子:

Here is the example Main() that i'm using for the moment:

int main(int argc, const char * argv[]){
    Pool* pool = new Pool();
    Client* c = new(pool) Client(pool);
    /*
    I'm using a parameter within operator new to pass the pool in for use and i'm also passing the pool as a constructor parameter so i can free up the memory in the destructor
    */

    delete c;
    delete pool;
    return 0;
}

到目前为止,我的代码工作,但我想知道是否有更好的方式实现这个?
请让我知道,如果我要求/做的任何事情是不可能的,坏的做法或只是简单的愚蠢。我现在在MacBook Pro,但我想保持我的代码跨平台,如果可能的话。

So far my code works, but I want to know if there is a better way to achieve this? Please let me know if anything I am asking/doing is simply impossible, bad practice or just simply dumb. I am on a MacBook Pro right now but i would like to keep my code cross platform if at all possible.

如果您有任何问题可以帮助我,请让我知道。

If you have any questions that would help you help me do let me know.

当然,先感谢任何可以帮助的人。

And of course, Thanks in advance to anyone who can help.

推荐答案

您可能会在返回的内存地址之前存储其他信息

You might store additional information just before the returned memory address

#include <iostream>
#include <type_traits>

class Pool {
public:
    static void* Alloc(std::size_t size) { return data; }
    static void Dealloc(void*) {}
private:
    static char data[1024];
};
char Pool::data[1024];


class Client
{
public:
    void* operator new(size_t size, Pool& pool);
    void operator delete(void* memory);
};


struct MemoryHeader {
    Pool* pool;
};


void* Client::operator new(size_t size, Pool& pool)
{
    auto header = static_cast<MemoryHeader*>(pool.Alloc(sizeof(MemoryHeader) + size));
    std::cout << "    New Header: " << header << '\n';
    header->pool = &pool;
    return header + 1;
}

void Client::operator delete(void* memory)
{
    auto header = static_cast<MemoryHeader*>(memory) - 1;
    std::cout << " Delete Header: " << header << '\n';
    header->pool->Dealloc(header);
}

int main()
{
    Pool pool;
    Client* p = new(pool) Client;
    std::cout << "Client Pointer: " << p << '\n';
    delete p;
    return 0;
}

这篇关于使用运算符new和运算符delete与自定义内存池/分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆