|
Получение свободного объема кучи, В ходе работы. CrossWorks 1.7.13 |
|
|
|
Mar 24 2009, 09:14
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче?
|
|
|
|
|
Mar 24 2009, 09:33
|

Профессионал
    
Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952

|
Цитата(YChebisheva @ Mar 24 2009, 12:14)  Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче? Адрес начала кучи вам даст функция malloc, например: char *p; p = malloc(1); // просим выделить 1 байт из кучи Размер кучи вы задаёте в свойствах проекта: Linker->Heap Size.
|
|
|
|
|
Mar 24 2009, 09:42
|

Местный
  
Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145

|
Цитата(etoja @ Mar 24 2009, 14:33)  Адрес начала кучи вам даст функция malloc, например:
char *p; p = malloc(1); // просим выделить 1 байт из кучи
Размер кучи вы задаёте в свойствах проекта: Linker->Heap Size. Вы уверены, что вновь выделяемый кусок будет именно в конце? (из любопытства)
|
|
|
|
|
Mar 24 2009, 09:45
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(YChebisheva @ Mar 24 2009, 12:14)  и сколько осталось свободного места в куче? Я оборачивал malloc/calloc/realloc/free в свои функции, в которых отслеживал задаваемый в параметрах размер. Типа того: Код static size_t mem_avail = 1024;// здесь размер кучи
void *malloc_prim(size_t size) { void *p; p = malloc(size); if(p!=NULL) mem_avail -=size; return p; } #define malloc(sz) malloc_prim(sz) УПС: порядок имеет значения #define после всей работы с настоящими malloc итд.
|
|
|
|
|
Mar 24 2009, 09:51
|

Местный
  
Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145

|
Цитата(YChebisheva @ Mar 24 2009, 14:14)  Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче? Лучше ипользовать какой-нибудь открытый аллокатор. Можно взять "монументальный" TLSF. В составе есть get_used_size. Ну а если со стандартным, то можно написать так: 1) Разметка всего хипа опред числом. 2) При маллоке портим значение выделяемой области. Меняем на др чилсло. 3) При осовбождении востанавливаем число. 4) При вычислении считаем количество "испорченных". Этот метод позовляет вычислить с достаточной степенью точности +\- 10 километров (шутка).
|
|
|
|
|
Mar 24 2009, 10:05
|

Местный
  
Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145

|
Цитата(klen @ Mar 24 2009, 14:56)  я использую FreeRTOS, там есть три реализации maloc/free, я взял одну из них и добавил в нее все что мне нада, в том числе и функцию возвращающуую остаток кучи, могу исходник кинуть если хотите Из всех 3х реализаций ровно ноль нормальных (Исключительно ИМХО). По-моему при создании фриртоса ставилась основная цель: сделать добротный движок, но не было цели сделать номальный аллокатор. Потому как хороших открытых и закрытых (в средах разработки) аллокаторов довольно много. Выбирайте на любой вкус.
|
|
|
|
|
Mar 24 2009, 12:07
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Парни, у меня не стоит задача, оптимизировать работу с памятью. Если я смотрю map-файл: .heap 0x40002458 0x400 0x40002458 __heap_start__ = . *(.heap) 0x40002858 . = (((__heap_start__ + __HEAPSIZE__) MAX_K .) ALIGN 0x4) *fill* 0x40002458 0x400 00 0x40002858 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) 0x00000001 . = ASSERT (((__heap_end__ >= __SRAM_segment_start__) && (__heap_end__ <= (__SRAM_segment_start__ + 0x4000))), error: .heap is too large to fit in SRAM memory segment) 0x40002858 __stack_load_start__ = (__heap_end__ ALIGN 0x4) Получается, что у меня куча начинается с 0x40002458. Объем 1 Кб. Его размер я могу поменять. Память выделяет с конца кучи к началу. Но сразу после инициализации, я делаю так: Код system_init(); spi0_mem_init(); ctl_global_interrupts_enable(); UART0Initialize(38400, InterruptCom0); char *s = (char*) malloc(1); printf(" %p ", s); free(s); Адрес s мне показывается - 284с. А конец кучи - 2858. Вроде как 13 байт. Но почему не 16? Ведь если следом запросить, к примеру 5 байт из кучи, адрес будет - 283с.
|
|
|
|
|
Mar 24 2009, 12:24
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(YChebisheva @ Mar 24 2009, 15:07)  Если я смотрю map-файл: 0x40002858 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) Если линкер поставляет Вам (компилеру) __heap_end__ , то зачем эти пассы: Код char *s = (char*) malloc(1); если можно просто s=__heap_end__;
|
|
|
|
|
Mar 24 2009, 12:39
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Цитата(_Pasha @ Mar 24 2009, 15:24)  Если линкер поставляет Вам (компилеру) __heap_end__ , то зачем эти пассы: Код char *s = (char*) malloc(1); если можно просто s=__heap_end__; В том то и беда, что на все эти попытки, имеем одно: Цитата '__heap_end__' undeclared (first use in this function
|
|
|
|
|
Mar 24 2009, 13:14
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
_Pasha, левые адреса возвращает: printf("%p", __heap_end__); 6f2cbea3
|
|
|
|
|
Mar 24 2009, 14:01
|

Местный
  
Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145

|
Цитата(YChebisheva @ Mar 24 2009, 18:14)  _Pasha, левые адреса возвращает: printf("%p", __heap_end__); 6f2cbea3  Описал так: extern void * __heap_start__; extern void * __heap_end__; volatile void * heap_start = &__heap_start__; volatile void * heap_end = &__heap_end__; Всё отлично.
|
|
|
|
|
Mar 25 2009, 08:49
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

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