moka
moka

Reputation: 4491

Overloading delete and retrieving size?

I am currently writing a small custom memory Allocator in C++, and want to use it together with operator overloading of new/ delete. Anyways, my memory Allocator basically checks if the requested memory is over a certain threshold, and if so uses malloc to allocate the requested memory chunk. Otherwise the memory will be provided by some fixedPool allocators. that generally works, but for my deallocation function looks like this:

void MemoryManager::deallocate(void * _ptr, size_t _size){
    if(_size > heapThreshold)
        deallocHeap(_ptr);
    else 
        deallocFixedPool(_ptr, _size);
}

So I need to provide the size of the chunk pointed to, to deallocate from the right place.

Now the problem is that the delete keyword does not provide any hint on the size of the deleted chunk, so I would need something like this:

void operator delete(void * _ptr, size_t _size){ 
    MemoryManager::deallocate(_ptr, _size); 
}

But as far as I can see, there is no way to determine the size inside the delete operator.- If I want to keep things the way it is right now, would I have to save the size of the memory chunks myself?

Upvotes: 4

Views: 2323

Answers (4)

imreal
imreal

Reputation: 10358

As of C++14 the Standard supports the second size parameter in the global delete allocation function. So want you want to do is possible natively now.

http://en.cppreference.com/w/cpp/memory/new/operator_delete

Upvotes: 2

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

For class type, C++ already supports it directly. For nonclass types, you need to store the size manually like the other solution shows.

struct MyClass {
  void operator delete(void *p, size_t size) {
    MemoryManager::deallocate(p, size);
  }
};

Upvotes: 2

Evan Teran
Evan Teran

Reputation: 90442

allocate more memory than neccessary and store the size information there. That's what your system allocator probably does already. Something like this (demonstrate with malloc for simplicity):

void *allocate(size_t size) {
    size_t *p = malloc(size + sizeof(size_t));
    p[0] = size;           // store the size in the first few bytes
    return (void*)(&p[1]); // return the memory just after the size we stored
}

void deallocate(void *ptr) {
    size_t *p = (size_t*)ptr; // make the pointer the right type
    size_t size = p[-1];      // get the data we stored at the beginning of this block

    // do what you need with size here...

    void *p2 = (void*)(&p[-1]); // get a pointer to the memory we originally really allocated
    free(p2);                   // free it
}

Upvotes: 7

JRL
JRL

Reputation: 78003

You could keep a map of memory address to size for your pool-allocated memory. When you delete, check if the pointer is in the map, if it is delete that size, if it isn't call regular delete.

Upvotes: 2

Related Questions