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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Фрагментация динамической памяти  (Прочитано 10322 раз)
0 Пользователей и 1 Гость смотрят эту тему.
stix
Гость
« : 29-11-2004 09:56 » 

Народ, поможите чем смогёте!
Проблема в следущем. Я резервирую куски памяти разной длины, а потом возвращаю, в результате образуются дыры в стеке. Памяти мало(всего 12кб), поэтому через определенное кол-во времени malloc выдает NULL.
Как решить таку проблему, как дефрагментировать стек?
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 29-11-2004 15:10 » 

stix, malloc() работает не со стеком процессора, а с отдельным блоком памяти.
По идее, если ф-ия free() реализована с умом, то при освобождении смежных блоков они должны объединятся. Многое зависит от твоей же програмы - как она занимает и освобождает динамическую память. Подумай об оптимизации. Например, если создаются N объектов, то память стоит занять за раз одним блоком, а не N раз по кусочку.
Записан

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

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

« Ответ #2 : 29-11-2004 15:41 » 

stix, можно ввести один уровень косвенности
Работать не с указателем, а с некоторым хендлом.  Во всех местах, где используется указатель, заменить на обращение к хендлу.

Код:
typedef struct | short id " mem_handle;

struct |short id; void * ptr; size_t size; " * alloc_table; /* таблица хранит отображение из id в указатель */
short alloc_table_len;

void * mem_handle_deref) mem_handle mh : |  
    /* найти в таблице элемент с id == mh.id */
    /* если найден, то вернуть соотв. указатель иначе NULL */
"

mem_handle alloc_mem) size_t size : |
    /* найти кусок памяти в списке свободной памяти, не меньше size */
    /* если не удалось, то попробовать переупорядочить записи в таблице */
    /* чтобы выделить кусок памяти подходящего размера */
    /* если память выделилась, то создать хендл, зарегистрировать в таблице и возвратить */
    /* иначе возвратить специальное значение, которое соотв. ошибке */
"

void free_mem_handle) mem_handle mh : |
    /* найти хендл в таблице */
    /* удалить хендл из таблицы */
    /* область памяти перенести в список свободной */
"
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
stix
Гость
« Ответ #3 : 30-11-2004 06:04 » 

Цитата: npak
stix, можно ввести один уровень косвенности
Работать не с указателем, а с некоторым хендлом.  Во всех местах, где используется указатель, заменить на обращение к хендлу.
...

npak, ты предлагаешь мне самому писать менеджер кучи?! Мне же нужно узнать есть ли процедура дефрагментации стека кучи или возможно ли самому написать такую процедуру?
Записан
comm
Гость
« Ответ #4 : 30-11-2004 07:51 » 

Цитата: stix
Цитата: npak
stix, можно ввести один уровень косвенности
Работать не с указателем, а с некоторым хендлом.  Во всех местах, где используется указатель, заменить на обращение к хендлу.
...

npak, ты предлагаешь мне самому писать менеджер кучи?! Мне же нужно узнать есть ли процедура дефрагментации стека кучи или возможно ли самому написать такую процедуру?


1. чтобы сделать процедуру дефрагментации кучи, нужно чтобы все указатели в программе хранились в одном месте иначе ты не сможешь независимо от программы перемещать блоки памяти, так как нужно менять сами указатели

2. если у тебя так мало памяти как ты указал, то я предполагаю что это ПО для встраиваемых систем, следовательно имеет смысл более внимательней отнестись к работе с памятью, и провести рефакторинг кода чтобы небыло этих самых "моножества malloc/free"
Записан
npak
Команда клуба

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

« Ответ #5 : 30-11-2004 11:34 » 

Цитата: stix
Цитата: npak
stix, можно ввести один уровень косвенности
Работать не с указателем, а с некоторым хендлом.  Во всех местах, где используется указатель, заменить на обращение к хендлу.
...

npak, ты предлагаешь мне самому писать менеджер кучи?! Мне же нужно узнать есть ли процедура дефрагментации стека кучи или возможно ли самому написать такую процедуру?


Да, я предлагаю сделать свой сжимающий аллокатор.  Учитывая, что у тебя всего 12 кб памяти, это вполне естественное решение. 1-2 кб на массив дескрипторов, и 10 кб на данные.

Ни в одной стандартной библиотеке С я не видел аллокаторов, которые могли бы переупорядочивать выделенные блоки памяти.

Надо либо поискать в инете, либо написать самому.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Migmile
Помогающий

ru
Offline Offline

« Ответ #6 : 30-11-2004 17:26 » 

Нет никаких стандартных дефрагментаторов, в такой задаче правильное решение - (IMXO) брать себе СРАЗУ всю память, а потом себе-же любимому и выделять сколько нужно. Не хватило кому-то - сдвинул остальных пользователей. А чдля этого придется использовать косвенные ссылки, а не прямые указатели, как и посоветовали выше стоящие товарищи.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines