gpt4 book ai didi

c - newlib : does it waste memory after one big failure allocation? 中的 malloc()

转载 作者:太空狗 更新时间:2023-10-29 15:25:54 26 4
gpt4 key购买 nike

我正在为 STM32F7 编写一个嵌入式软件,我的 libc 是 newlib-2.4.0.20160527。

我已经实现了_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() 之后工作正常)。

我是否遗漏了什么,或者这是 newlib 中的错误或预期行为?

最佳答案

由于 newlib/libc/stdlib/mallocr 中的错误 malloc_extend_top() 例程,newlib 的 malloc() 在分配整个堆内存时无法正常工作。 c:2137。成功调用 _sbrk()

  brk = (char*)(MORECORE (sbrk_size)); /* MORECORE = _sbrk */

/* Fail if sbrk failed or if a foreign sbrk call killed our space */
if (brk == (char*)(MORECORE_FAILURE) ||
(brk < old_end && old_top != initial_top))
return;

它会尝试计算校正以适应页面对齐方式:

/* Guarantee alignment of first new chunk made from this space */
front_misalign = (POINTER_UINT)chunk2mem(brk) & MALLOC_ALIGN_MASK;
if (front_misalign > 0)
{
correction = (MALLOC_ALIGNMENT) - front_misalign;
brk += correction;
}
else
correction = 0;

/* Guarantee the next brk will be at a page boundary */
correction += pagesz - ((POINTER_UINT)(brk + sbrk_size) & (pagesz - 1));

校正总是正的,因为即使分配完美匹配,它也会尝试分配下一个整页。例如,如果页面大小为 4096 并且 brk + sbrk_size = 4096*n,表达式 4096 - ((brk + sbrk_size) & 4095)将给出 4096,因此需要下一个空页,但没有空间。

例程没有正确处理这种情况,只留下分配的数据(brk 值),导致永久“无法释放”的整个堆分配。太浪费了:-)

关于c - newlib : does it waste memory after one big failure allocation? 中的 malloc(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39088598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com