Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2]  Все   Вниз
  Печать  
Автор Тема: Стандартный менеджер памяти в С  (Прочитано 42307 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #30 : 26-01-2017 11:04 » 

Код: (C)
static void add_points_to_pool(point_pool* pool, point_index new_points_index, size_t count) {
    point_index n = new_points_index + (point_index)count - 1;
    pool->points[n].next = pool->free_points;

    for (--n; n > new_points_index - 1; --n) {
        pool->points[n].next = n + 1;
    }

    pool->free_points = new_points_index;
}

point_pool* create_point_pool(size_t prealocate_count, size_t step) {
    point_pool* pool = (point_pool*)malloc(sizeof(point_pool));

    if (pool == 0) return 0;

    pool->points = (point*)malloc(sizeof(point) * prealocate_count);

    if (pool->points == 0) {
        free((void*)pool);
        return 0;
    }

    pool->free_points = POINT_END_INDEX;
    pool->total = prealocate_count;
    pool->step = step;
    add_points_to_pool(pool, 0, prealocate_count);
    return pool;
}
Рассмотрим работу:
Код: (C)
point_pool* my_pool = create_point_pool(5, 5);
После создания бассейна без свободных мест конструктор вызывает:
Код: (C)
add_points_to_pool(pool, 0, 5);
В дальнейшем:
n = 0 + 5 - 1 = 4
pool->points[4].next = <T>
и цикл от 3 пока n > (new_point_index = 0) - 1, то есть пока n > 0xFFFFFFFF, то есть ни одного раза? Впрочем, это мелочи, суть ясна.
pool->points[3].next = 4;
pool->points[2].next = 3;
pool->points[1].next = 2;
pool->points[0].next = 1;
free_points = 0;
Далее необходимо найти в бассейне конкретную свободную точку:
Код: (C)
point_index my_index = alloc_point(my_pool);
idx = 5;
Вызывает:
Код: (C)
remove_point_from_list(&(pool->free_points), &(pool->points[0]));
В результате: free_points = 1. А возвращается 0;
Вот теперь по индексу 0 можно что-то записать.

API не очень очевидное, позже попробую понять, как это работать будет в случае удаления данных из середины. Пока вижу расширяющийся вверх список до фрагментации.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #31 : 26-01-2017 15:05 » 

Что есть "idx=5"? — совсем не понял.

Что здесь не очевидно? У нас менеджер массива: выделяет, следит, сам расширяет. Память освобождается только при уничтожения пула. Я бы еще assert добавил для тестов. Если работать только через API и не сохранять у себя указатели, проблем не будет.

Если тебе что-то надо сохранить в файле, пишешь соотв. функцию:

Код: (C)
#include <stdio.h>

size_t save_point_list_to_file(FILE *f, pool *pool, point_index head, const size_t count = 0) {
    off64_t head_pos = ftello64(f);
    uint32_t real_count = (uint32_t)count;

    if (fwrite((void*)&real_count, sizeof(real_count), 1, f) == 0) {
        return 0;
    }

    real_count = 0;

    point_list_for_each(pool, head) {
        if (fwrite((void*)p, sizeof(point), 1, f) == 0) {
            return 0;
        }

        ++real_count;

        if (count == real_count) {
            break;
        }
    }

    if (count != real_count) {
        off64_t end_pos = ftello64(f);
        fseeko64(f, head_pos, SEEK_SET);
        fwrite((void*)&real_count, sizeof(real_count), 1, f);
        fseeko64(f, end_pos, SEEK_SET);
    }
   
    return (size_t)real_count;
}

size_t load_point_list_from_file(FILE *f, pool *pool, point_index *head) {
    uint32_t count;

    if (fread((void*)&count, sizeof(count), 1, f) == 0) {
        return 0;
    }

    for (size_t n = 0; n < count; ++n) {
        point_index idx = alloc_point(pool);
        point *p = get_point(pool, idx);

        if ((fread((void*)p, sizeof(point), 1, f) == 0) {
            free_point(pool, idx);
            free_point_list(pool, head);
            return 0;
        }

        add_point_to_list(head, p, idx);
    }

    return count;
}
« Последнее редактирование: 26-01-2017 19:07 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #32 : 26-01-2017 18:12 » new

Спасибо.

Прикреплю изображение по размышлениям.

* diag_4.jpg (622.29 Кб - загружено 1039 раз.)
Записан
Страниц: 1 [2]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines