Я пишу встроенное программное обеспечение для STM32F7, а мой libc - это newlib-2.4.0.20160527.malloc() в newlib: это потеря памяти после одного большого отказа?
Я реализовал _sbrk()
следующим образом:
extern intptr_t g_bss_end; /* value after the last byte in .bss */
extern intptr_t g_msp_lim; /* stack buffer starts at this address */
intptr_t _sbrk(ptrdiff_t heap_incr)
{
static intptr_t heap_end = 0;
intptr_t prev_heap_end;
intptr_t new_heap_end;
if(heap_end == 0) {
heap_end = (intptr_t)&g_bss_end;
}
prev_heap_end = heap_end;
new_heap_end = prev_heap_end + heap_incr;
if(new_heap_end >= g_msp_lim) {
errno = ENOMEM;
return -1;
}
heap_end = new_heap_end;
return prev_heap_end;
}
Тогда, когда я делаю следующее:
/* total capacity of my heap is 0x40000 */
void * mem = malloc(0x40000);
free(mem); mem = 0;
mem = malloc(0x40000);
все работает отлично (т.е. таНос возвращает ненулевое значение в два раза).
Но когда я делаю следующее (для целей тестирования):
for(int32_t sz = 0x50000; sz >= 0; sz--) {
void * mem = malloc(sz);
if(mem != 0) {
__BKPT();
free(mem);
break;
}
}
каждый malloc()
не удается, даже malloc(0)
(т.е. __BKPT()
является никогда не достигало). Итак, на куче нет выделенной памяти (я не получил mem != 0
, поэтому я не могу даже free()
что-то), а также нет доступной памяти.
Я ожидал malloc()
на провал для каждого sz > 0x40000
и успеха для каждого sz <= 0x40000
(предполагается, что free()
работает отлично после каждого malloc()
).
Я что-то пропустил, или это либо ошибка, либо предполагаемое поведение в newlib?
Что говорит отладчик? Прошли ли вы через код? Примечание: использование распределенной динамической памяти на основе кучи, такой как 'malloc' во встроенных системах, чаще всего является плохим идеей и запрещено многими стандартами кодирования по уважительным причинам. Особенно детерминированное поведение и гарантированное распределение. Оцените использование пулов или других мер, таких как статические переменные, прежде чем даже подумать о 'malloc' и т. Д.! – Olaf
О, и используйте макрос 'NULL' с указателями. '0', поскольку константа нулевого указателя действительна, но плохая привычка от программистов на С ++. В C++ 11 был введен «nullptr» по уважительным причинам. (Желание C11 последовало за ними) – Olaf
Я прошел через свой код (я проверил значения 'mem';' __BKPT() 'также была точкой останова). Чтобы войти в код newlib с помощью gdb, я перекомпилирую его с помощью '-g3 -O0'. Я хочу иметь работу 'snprintf', которая полагается на' malloc'. Должен ли я начинать поиск альтернатив snprintf? Мне не нужно «malloc» ни для чего другого. –