crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Работа распределителей памяти, вопросы и ответы
AD
  опции профиля:
сообщение 2.7.2009, 11:32
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 65 раз(а)




Репутация:   17  


Хотел задать вопрос больше теоретического плана: как работают распределители памяти? Ну в качестве примера возьму код из моей программы уже приводимый на форуме.
Есть вектор log, каждый элемент которого содержит вектор params, с набором значений параметров.

Когда params был массивом, то в принципе распределение можно сделать уже указанным способом: выделять какому-то буферу большой кусок памяти, а потом "раздавать" эту память массивам params! Т.е. операция выделения памяти будет происходить не на каждой итерации чтения новой записи из файла.
PARAMVALUE* params; /// вместо указанного типа может быть абсолютно любой - сейчас важен принцип работы а не конкретика
// где-то
int param_buf_count = 0;
const int BUFF_SIZE = 2048;
char* param_buff = 0;

// ........................ Код чтения
LOGRECORD t;
if(param_buf_count >= BUFF_SIZE) param_buf_count = 0;
if(param_buf_count == 0)
{
param_buff = new char[rec_descr.size() * BUFF_SIZE];
}
t.params = param_buff + param_buf_count * rec_descr.size();
++param_buf_count;

// какие-то действия с заполнением вектора



Если же params - вектор, то следует писать распределитель памяти. Но при этом визуально код чтения не меняется и получается, что на каждой итерации идет выделение памяти. Или я что-то не так понимаю?
std::vector<PARAMVALUE, pool_alloc<PARAMVALUE>> params; /// вектор с собственным распределителем

// ........................ Код чтения
LOGRECORD t(rec_descr.size());

// какие-то действия с заполнением вектора


Как видно по коду, то в первом случае выделение происходит только при определенных условиях, а во 2 случае таких условий не видно. Каким же образом тогда происходит распределение памяти?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 3.7.2009, 8:57
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 67 раз(а)




Репутация:   17  


Ну почитай ты книжки. Распределение памяти - это не тот момент который удобно объяснять на форуме на пальцах.
У того же Страуструпа описано и у Саттера вроде...

Я бы, в подобном случае вообще свой механизм сделал - единый блоковый контейнер для PARAMVALUE и boost::range в LOGRECORD.

Код использования был бы примерно такой:

struct LOGRECORD {
  std::pair<PARAMVALUE*, PARAMVALUE*> params;    ///< массив параметров
  ...
};

struct LogReader {
  ...
  bool tRead();
  bool parseBlock(LOGRECORD& t);
  private:
    ParamValueChihkContainer<PARAMVALUE> params;
};

bool LogReader::tRead() {
  ...
  while(_file -> read((char*)&var, sizeof(var)) > 0) {
    ...
    case 0001:
      log.append(LOGRECORD(rec_descr.size()));
      parseBlock(log.last());
...
  return file_read;
}

/// Разбор одной записи
bool LogReader::parseBlock(LOGRECORD& t) {
  ...
  t.params = params.constrict(rec_descr.size())
  ...
                    t.params[i] = (*jter) -> GetValue(var);
                    t.params[i].evn = 0;
  ...
  return true;
}

tymplate <T>
struct ParamValueChihkContainer {
  std::pair<T*, T*> constrict(size_t n);
  ...
};

Где ParamValueChihkContainer::constrict отдаёт std::pair<T*, T*> на в текущем распределённом блоке, если там есть место, или распределяет новый блок, если места нет.
Опять же, для его реализации я бы воспользовался boost::pool. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 3.7.2009, 9:20
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 65 раз(а)




Репутация:   17  


Саттера дочитываю! :) Как раз дошел до распределения памяти, но не успел дочитать еще! :))))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 21.5.2018, 13:36