реклама на сайте
подробности

 
 
> Работа с Heap, Из любопытства, но для понимания
SasaVitebsk
сообщение Feb 15 2007, 15:27
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Столкнулся с интересным феноменом. Я его не понимаю. Может кто объяснит популярно.
Сначала приведу пример:

Есть два варианта:
1)
Код
   OW_Rom_Device=CurrentAddr=malloc(8);            // Çàðåçåðâèðîâàòü ïàìÿòü ïîä ROM


2)
Код
   OW_Rom_Device=malloc(0);
....
   CurrentAddr=malloc(8);            // Çàðåçåðâèðîâàòü ïàìÿòü ïîä ROM


В первом случае адреса OW_Rom_Device и CurrentAddr - одинаковы.
Во втором CurrentAddr больше на 2 байта.

Вопросы: почему и зачем?
(Пояснения:между данными операторами с кучей никто не работает; если вместо malloc(0) ввести malloc(1) разница будет 3 байта)

Очень похоже что компилятор записывает адрес кучи, но зачем?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SasaVitebsk
сообщение Feb 16 2007, 02:41
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Перечитал ещё раз free и теперь всё уложилось в голове.

Всё то, о чём Вы писали, для меня было понятно. Просто я решил, что конкретная реализация для AVR в используемом компиляторе - упрощена. На эту мысль меня подтолкнула функция free (точнее даже то, что её аргументом является указатель). Прочитал невнимательно, и ошибочно решил, что указатель указывает на адрес, начиная с какого нужно память освободить. smile.gif Ну а воображение вмиг дорисовало всё остальное. smile.gif Раз так, то всё просто. По malloc забираю по free освобождаю. А данные идут одним куском.
Кроме того, в принципе всё согласовалось. Такой способ возможен и в паскале к примеру (getmem/freemem). Я для приличия поискал другой способ освобождения памяти, но для Си - ненашёл. Ну и успокоился, отнеся данный недостаток на Embedded системы. В общем то решил, что при необходимости пишется свой диспетчер кучи и там - делай что хочешь. Или что хочет zltigo к примеру. smile.gif

Теперь трохи понятно как поступил компилятор.

1) Оператор
Код
OW_Rom_Device=CurrentAddr=malloc(8);
он разложил на два. Первый выделение под объект под указателем CurrentAddr 8 байт (и пометил его указателем в куче хотя я его не увидел так как он был в самой вершине). А вторым оператором просто присвоил значение указателя CurrentAddr указателю OW_Rom_Device. Таким образом разрыва не было, так как не было двух malloc.
2) Поскольку я вызывал функцию malloc без присваивания, то, соответственно нет объекта по которому может осуществляться free, и компилятор (какой умный) продолжил выделение памяти сплошным куском. Ну а я оставался в блаженном неведении своего невежества. biggrin.gif

Теперь я понимаю и разделяю возмущение zltigo "почему только два байта". Надо же как-то пометить конец данных. Я бы действительно указал размер зарезервированной области. А то, возвращаясь к примеру с A,B,C, - если я после освобождения B попытаюсь опять зарезервировать область памяти и она вполне влезет в "дырку", то как компилятор это чухнет. Или он при удалении весь блок сдвинет? Надо будет попробовать, как по свободнее буду. smile.gif

А вы говорите. Всегда надо до конца разбираться. Иначе непонятки потом боком вылезут.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 16 2007, 03:09
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(SasaVitebsk @ Feb 16 2007, 01:41) *
если я после освобождения B попытаюсь опять зарезервировать область памяти и она вполне влезет в "дырку", то как компилятор это чухнет.

А ему какое дело где ему память выделят?
Цитата
Или он при удалении весь блок сдвинет? Надо будет попробовать, как по свободнее буду. smile.gif

Пробовать - не надо. Просто подумайте куда после такого сдвига будет указывать указатель ранее выданный в качестве валидного для блока C smile.gif
Цитата
А вы говорите. Всегда надо до конца разбираться. Иначе непонятки потом боком вылезут.

Разбираться в общем-то нечего, ибо функционал минималистичен а закладыватся на знание интимных
подробностей чужого произвльного менеджера это жуткий моветон sad.gif
Цитата
при необходимости пишется свой диспетчер кучи и там - делай что хочешь. Или что хочет zltigo к примеру.

Я в любом случае обеспечиваю полную совместимость с malloc() realloc() free() и за счет знания внутренней структуры имею дополнительные ранее упомянутые функциональные возможности
не зависящие от библиотек какого либо компилятора.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 17 2007, 00:01
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Feb 16 2007, 04:09) *
Цитата(SasaVitebsk @ Feb 16 2007, 01:41) *

Или он при удалении весь блок сдвинет? Надо будет попробовать, как по свободнее буду. smile.gif

Пробовать - не надо. Просто подумайте куда после такого сдвига будет указывать указатель ранее выданный в качестве валидного для блока C smile.gif

Да, всё таки иногда надо думать. biggrin.gif Придётся с этим смириться. biggrin.gif
Цитата
Цитата

если я после освобождения B попытаюсь опять зарезервировать область памяти и она вполне влезет в "дырку", то как компилятор это чухнет.

А ему какое дело где ему память выделят?


Вот тут я не понял. (Опять не укладывается smile.gif ).

Итак давайте сначала.

Резервируем три области по 10б к примеру. A,B,C.
Компилятор в куче на каждую размещает один указатель и 10б и уменьшает размер кучи на 36 байт соответственно.

Освобождаю переменную B.
Компилятор
а) может освободить просто 10 байт и сохранить указатель на дырку. Тогда по разнице указателей, он может высчитать размер дыры, что обеспечит нормальное выделение/освобождение памяти. Правда при длительной работе и разноразмерных переменных может возникнуть ситуация с большим количеством дырок и отсутствием - необходимого размера. Так сказать проблема OS CP/M, решаемая только дефрагментацией кучи по временам, но тут возникают проблемы описанные выше.
б) может освободить все 12 байт памяти, но не увеличивать размер кучи. Я не вижу способа работы таким образом.

Короче у меня тупик.

Если не надоело, то может кто ответит.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- SasaVitebsk   Работа с Heap   Feb 15 2007, 15:27
- - makc   Разница между адресами во втором варианте будет за...   Feb 15 2007, 15:36
- - _Bill   Цитата(SasaVitebsk @ Feb 15 2007, 15:27) ...   Feb 15 2007, 15:54
- - Сергей Борщ   Цитата(SasaVitebsk @ Feb 15 2007, 14:27) ...   Feb 15 2007, 16:17
|- - zltigo   Цитата(Сергей Борщ @ Feb 15 2007, 15:17) ...   Feb 15 2007, 20:34
- - SasaVitebsk   В общем-то спасибо за теорию. Познавательно. 2 zlt...   Feb 15 2007, 23:15
|- - zltigo   Цитата(SasaVitebsk @ Feb 15 2007, 22:15) ...   Feb 16 2007, 01:18
|- - Сергей Борщ   Цитата(SasaVitebsk @ Feb 15 2007, 22:15) ...   Feb 16 2007, 01:24
|- - zltigo   Цитата(Сергей Борщ @ Feb 16 2007, 00:24) ...   Feb 16 2007, 01:49
|- - zltigo   Цитата(SasaVitebsk @ Feb 16 2007, 23:01) ...   Feb 17 2007, 01:32
|- - Сергей Борщ   Цитата(SasaVitebsk @ Feb 16 2007, 23:01) ...   Feb 17 2007, 16:20
- - SasaVitebsk   Всем спасибо за приятную, интересную и очень содер...   Feb 17 2007, 21:42
|- - Сергей Борщ   Цитата(SasaVitebsk @ Feb 17 2007, 20:42) ...   Feb 18 2007, 00:50
|- - SasaVitebsk   Цитата(Сергей Борщ @ Feb 18 2007, 01:50) ...   Feb 18 2007, 20:11
|- - Сергей Борщ   Цитата(SasaVitebsk @ Feb 18 2007, 19:11) ...   Feb 18 2007, 20:33
- - WHALE   Какие 8 марта,вы чё?23 февраля на носу,и многотомн...   Feb 18 2007, 21:10


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 12:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01413 секунд с 7
ELECTRONIX ©2004-2016