Аллокатор наподобие Dinkumware std::string
От: Went  
Дата: 16.09.09 12:34
Оценка:
Добрый день. Еще никогда не работал с аллокаторами, и вот получилось, что нужно получить контейнер, который внешне как вектор, но выделений памяти не делает, а просто проецирует все выделения в статический массив ограниченной длины. После того, как поковырялся в доках, решил, что лучше не писать новый контейнер, а создать специальный аллокатор. В результате получилась такая вот ерунда (это только первые наброски):
template<typename T, Size S>
class PoolAllocator
{
public:
  typedef T                 value_type;
  typedef value_type*       pointer;
  typedef value_type&       reference;
  typedef const value_type* const_pointer;
  typedef const value_type& const_reference;
  typedef size_t            size_type;
  typedef ptrdiff_t         difference_type;

  static const Size object_size = sizeof(T);
  static const Size pool_size = S;
  static const Size total_size = object_size * pool_size;

  template<class Other>
  struct rebind
  {
    typedef PoolAllocator<Other, S> other;
  };

  void deallocate(pointer ptr, size_type)
  {
    // Ничего не делаем
  };

  pointer allocate(size_type count)
  {
    // Тоже ничего не делаем
    return reinterpret_cast<pointer>(m_pool);
  }

  pointer allocate(size_type count, const void _FARQ *)
  {
    // Игнорим
    return allocate(count);
  }

  void construct(pointer ptr, const T& val)
  {
    new (ptr) T(val);
  }

  void destroy(pointer ptr)
  {
    ptr->~T();
  }

  Size max_size() const
  {    
    return pool_size;
  }

protected:
  unsigned char m_pool[total_size];
};

Эта ерунда не работает, и вот почему. В процессе добавления нового элемента вектор выделяет память на новых и старых членов вместе и после этого копирует в получившийся объем старые. Но код копирования таков, что сначала он занимает новые элементы значениями по умолчанию, а так как выделенная область фактически совпадает со старой, то перетирает оба значения. Таким образом в результате добавления старые элементы затираются значениями по умолчанию. Что делать?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.