Информация об изменениях

Сообщение Re[2]: Собственный аллокатор с задаваемым выделением памяти от 27.03.2018 8:18

Изменено 27.03.2018 8:20 avovana

Re[2]: Собственный аллокатор с задаваемым выделением памяти
Спасибо за ответы!

M>Всё когда-то бывает в первый раз

Представляю, что разобраться будет не просто
Уже порядочно запутался, т.к. не могу найти просто мануала, а везде какие-то куски.

M>По идее, аллокатор для map вызывается для аллокации памяти для каждого узла. Не совсем понятен фокус с выделением куска памяти *Size


M>Можно описать, чего хотелось и что получилось или не получилось?


Сейчас есть такое задание — чтобы саллоцироватьп память заранее для последующего конструирования элементов.
Вот и хотелось как-нибудь(к примеру параметром) передать под сколько элементов нужно заранее саллоцировать память.
Как в std::vector::reserve(Size).

Теперь мне понимаю, что метод allocate у аллокатора std::map будет вызывать каждый раз.

M>А знаешь почему у std::vector есть метод reserve, а у std::map его нет? Ведь про него не забыли — существует причина по которой он отсутствует

No...

M>Так и не получится. std::map будет всегда запрашивать у аллокатора память для одного узла дерева за раз.

M>Но выделять память блоками, конечно можно. Просто для этого тебе нужно использовать stateful-аллокатор.
M>То есть твой пользовательский аллокатор, который передаётся в std::map, должен хранить указатель (или ссылку) на родительский аллокатор или, как его лучше назвать, memory pool.
M>И в методе allocate не выделять память вызовом malloc, а отдавать указатель на уже выделенную память в родительском пуле. А если её там не хватает, то пусть уже родительский пул аллоцирует очередной большой блок памяти.

Прочитал статью arena allocator.
Мне кажется, Вы говорите примерно об этом.
Сложно она у меня пошла. Такое чувство, что авторы, пишущие на данную тему уже подразумевают, что читатель знает это, это и это + основную логику работы аллокатора.
А для новичка(для меня) очень сложно.
Самое простое, что нашел из книги Джсатиса — myalloc.cpp.

1. Правильно ли я понимаю, что в аллокатор:
  template <typename T>
  struct Allocator {
  ...
  }

нужно будет добавить объект pool?

2. Правильно ли я понимаю, что:
стоит реализовать метод pointer allocate(size_type n) не так:
    pointer allocate(size_type n) {

      void *ptr = malloc(sizeof(value_type) * n);
      if (ptr == nullptr)
        throw std::bad_alloc();
      return static_cast<pointer>(ptr);
    }

А использовать внутри этот самый pool вместо malloc'a внутри которого и будет реализована логика выделения памяти и предоставления указателя void *ptr наверх(в allocate).
Т.е. фактически строчка:
void *ptr = malloc(sizeof(value_type) * n);
замениться на:
void *ptr = pool.getMemory(sizeof(value_type) * n);
?
Re[2]: Собственный аллокатор с задаваемым выделением памяти
Спасибо за ответы!

M>Всё когда-то бывает в первый раз

Представляю, что разобраться будет не просто
Уже порядочно запутался, т.к. не могу найти простого мануала, а везде какие-то куски.

M>По идее, аллокатор для map вызывается для аллокации памяти для каждого узла. Не совсем понятен фокус с выделением куска памяти *Size


M>Можно описать, чего хотелось и что получилось или не получилось?


Сейчас есть такое задание — чтобы саллоцироватьп память заранее для последующего конструирования элементов.
Вот и хотелось как-нибудь(к примеру параметром) передать под сколько элементов нужно заранее саллоцировать память.
Как в std::vector::reserve(Size).

Теперь мне понимаю, что метод allocate у аллокатора std::map будет вызывать каждый раз.

M>А знаешь почему у std::vector есть метод reserve, а у std::map его нет? Ведь про него не забыли — существует причина по которой он отсутствует

No...

M>Так и не получится. std::map будет всегда запрашивать у аллокатора память для одного узла дерева за раз.

M>Но выделять память блоками, конечно можно. Просто для этого тебе нужно использовать stateful-аллокатор.
M>То есть твой пользовательский аллокатор, который передаётся в std::map, должен хранить указатель (или ссылку) на родительский аллокатор или, как его лучше назвать, memory pool.
M>И в методе allocate не выделять память вызовом malloc, а отдавать указатель на уже выделенную память в родительском пуле. А если её там не хватает, то пусть уже родительский пул аллоцирует очередной большой блок памяти.

Прочитал статью arena allocator.
Мне кажется, Вы говорите примерно об этом.
Сложно она у меня пошла. Такое чувство, что авторы, пишущие на данную тему уже подразумевают, что читатель знает это, это и это + основную логику работы аллокатора.
А для новичка(для меня) очень сложно.
Самое простое, что нашел из книги Джсатиса — myalloc.cpp.

1. Правильно ли я понимаю, что в аллокатор:
  template <typename T>
  struct Allocator {
  ...
  }

нужно будет добавить объект pool?

2. Правильно ли я понимаю, что:
стоит реализовать метод pointer allocate(size_type n) не так:
    pointer allocate(size_type n) {

      void *ptr = malloc(sizeof(value_type) * n);
      if (ptr == nullptr)
        throw std::bad_alloc();
      return static_cast<pointer>(ptr);
    }

А использовать внутри этот самый pool вместо malloc'a внутри которого и будет реализована логика выделения памяти и предоставления указателя void *ptr наверх(в allocate).
Т.е. фактически строчка:
void *ptr = malloc(sizeof(value_type) * n);
замениться на:
void *ptr = pool.getMemory(sizeof(value_type) * n);
?