STM32F7 용 임베디드 소프트웨어를 작성 중이며 libc는 newlib-2.4.0.20160527입니다. 다음과 같이 내가 _sbrk()
을 구현 한newlib의 malloc() : 하나의 큰 실패 할당 후에 메모리를 낭비합니까?
: 나는 다음 작업을 수행 할 때
다음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을 두 번 비제로 반환). 내가 (테스트 용) 다음 작업을 수행 할 때
그러나 : 모든 malloc()
실패
for(int32_t sz = 0x50000; sz >= 0; sz--) {
void * mem = malloc(sz);
if(mem != 0) {
__BKPT();
free(mem);
break;
}
}
, 심지어 malloc(0)
(즉, __BKPT()
입니다 는 도달하지 못했다). 그래서 실제로 힙에 할당 된 메모리가 없습니다 (나는 mem != 0
을 얻지 못했고 따라서 free()
뭔가도 없을 수 있습니다) 또한 사용 가능한 메모리도 없습니다.
sz > 0x40000
실패와
sz <= 0x40000
이 (
free()
를 가정하는 것은 각
malloc()
후 잘 작동) 모든 성공하여야
malloc()
을 기대했다.
나는 뭔가를 놓친 적이 있습니까, 아니면 newlib에서 버그입니까?
디버거는 무엇을 말합니까? 코드를 단계별로 실행 했습니까? 참고 : 임베디드 시스템에서'malloc '과 같은 힙 기반 동적 메모리 할당을 사용하는 것은 나쁜 아이디어이며 좋은 이유 때문에 많은 코딩 표준에 의해 허용되지 않습니다. 특히 결정 론적 행동과 보장 된 배정. 정적 변수와 같은 풀 또는 다른 측정 값의 사용을 평가하기 전에 'malloc'등에 대해서 생각해보십시오! – Olaf
아, 그리고 포인터와 함께'NULL' 매크로를 사용하십시오. null 포인터 상수로 '0'은 유효하지만 C++ 프로그래머에게는 나쁜 습관입니다. C++ 11은 좋은 이유로 nullptr을 도입했습니다. (소원 C11이 따라 갔다.) – Olaf
나는 (mem의 값을 검사하고, __BKPT()도 중단 점이었다) 코드를 밟았다. gdb로 newlib의 코드를 가져 오려면 지금 그것을'-g3 -O0'으로 다시 컴파일하고 있습니다. 'malloc '에 의존하는'snprintf'작업을하고 싶습니다. 'snprintf '대안 검색을 시작해야합니까? 나는 다른 것을 위해 malloc을 필요로하지 않는다. –