我正在爲STM32F7編寫一個嵌入式軟件,我的libc是newlib-2.4.0.20160527。newlib中的malloc():一次大的故障分配後會浪費內存嗎?
我已經實現_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);
一切正常(即malloc的返回非零的兩倍)。
但是,當我這樣做(用於測試目的):
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()
正常工作)取得成功。
我錯過了什麼,或者這是bug或在newlib中的預期行爲?
調試器說什麼?你是否已經完成了代碼?注意:在嵌入式系統中使用基於堆的動態內存分配像'malloc'通常是一個壞主意,許多編碼標準出於正當理由不允許使用這種分配。值得注意的是確定性行爲和保證分配。在甚至考慮'malloc'等之前,先評估池或其他度量方法(如靜態變量)的使用! – Olaf
哦,並用指針的'NULL'宏。 '0'作爲空指針常量是有效的,但是C++程序員的壞習慣。出於好的理由,C++ 11引入了'nullptr'。 (希望C11跟着他們) – Olaf
我通過我的代碼(我檢查了'mem'的值;'__BKPT()'也是一個斷點)。爲了使用gdb進入newlib的代碼,我現在用'-g3 -O0'重新編譯它。我想要工作'snprintf',它依賴'malloc'。我應該開始搜索'snprintf'選項嗎?我不需要'malloc'來做其他事情。 –