Trevor Hickey
Trevor Hickey

Reputation: 37834

Can I write a custom allocator to decide the reallocation amount of std::vector?

To my understanding, a custom allocator must fit the requierements of the Allocator Concept. Based on that interface though, I can't see how I would choose a new allocation amount when the vector has run out of reserve.

For example, the current implementation on my machine will double the allocation size every time the reserve is exceeded during a push_back(). I'd like to provide a custom allocator that is slow and memory conscious. It will only allocate the previous capacity+1 to accomodate the new element.

These are the interfaces of the concept I'm looking at:

a.allocate(n)
a.allocate(n, cvptr) (optional) 

I've made a working boilerplate allocator like so:

#include <limits>
#include <iostream>

template <class T> class MyAlloc {
public:

  // type definitions
  typedef T value_type;
  typedef T *pointer;
  typedef const T *const_pointer;
  typedef T &reference;
  typedef const T &const_reference;
  typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;

  pointer address(reference value) const {
    return &value;
  }
  const_pointer address(const_reference value) const {
    return &value;
  }
  size_type max_size() const throw() {
    return std::numeric_limits<std::size_t>::max() / sizeof(T);
  }
  pointer allocate(size_type num, const void * = 0) {
    return (pointer)(::operator new(num * sizeof(T)));
  }
  void construct(pointer p, const T &value) {
    new ((void *)p) T(value);
  }
  void destroy(pointer p) {
    p->~T();
  }
  void deallocate(pointer p, size_type num) {
    ::operator delete((void *)p);
  }
};

Looking at the allocate function:

pointer allocate(size_type num, const void * = 0) {
  return (pointer)(::operator new(num * sizeof(T)));
}

I could allocate more or less memory here, but I don't see a way of reporting that back to the vector so that it knows what its current capacity is.

Maybe this falls outside the responsibility of an allocator?

Upvotes: 1

Views: 893

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473457

The STL model that C++ inherited is based on a specific division between container and allocator. The purpose of an allocator is to provide the memory that someone requests. The decision about how much memory to allocate is entirely up to the container, without regard for which allocator it uses to provide that memory.

That's the model C++ uses. You could write your own vector-like container that allows its allocator to specify how much it should allocate. But other than that, no.

Upvotes: 5

Related Questions