MALLOC(3)

명칭
malloc, calloc, realloc, free, reallocf - 범용의 메모리 할당을 위한 함수군

프로그램 라이브러리
libc

서식
<stdlib.h> void * malloc(size_t size) void * calloc(size_t number, size_t size) void * realloc(void *ptr, size_t size) void * reallocf(void *ptr, size_t size) void free(void *ptr) char * malloc_options;

해설
malloc() 함수는, size 바이트의 메모리를 할당합니다. 할당할 수 있었던 공간은 (가능한 포인터 강제의 후에) 모든 타입의 오브젝트를 보존할 수 있도록(듯이) 적절히 조정됩니다. 그 공간의 길이가 적어도 pagesize 바이트인 경우 ( getpagesize(3) 참조), 돌려주어지는 메모리는 페이지 경계가 조정되고 있겠지요. malloc() 에 실패하면(자), NULL 포인터가 돌려주어집니다.

통상 malloc() 하지만 돌려주는 메모리는, 0 의 바이트로 초기화되어 없다 일로 주의해 주세요.

calloc() 함수는, number 개의, 길이가 size 인 오브젝트에 공간을 할당합니다. 이 함수를 호출한 결과는, 할당할 수 있었던 메모리가 0 의 바이트에 명시적으로 초기화되고 있는 것을 제외하면, 인수 “number * size” 그리고 malloc() (을)를 호출한 결과와 같습니다.

realloc() 함수는, ptr 그리고 참조되는, 이전에 할당할 수 있었던 메모리의 사이즈를 size 바이트로 변경합니다. 새로운 사이즈와 낡은 사이즈 가운데, 작은 (분)편의 사이즈까지의 메모리 내용은 변경되지 않습니다. 새로운 사이즈가 큰 경우, 새롭게 할당할 수 있었던 부분의 메모리의 값은 미정도리입니다. 요구된 메모리를 할당할 수가 없었던 경우는 NULL 하지만 돌려주어집니다만, ptr 하지만 참조하는 메모리는 유효해 변경되고 있지 않습니다. ptr 하지만 NULL 인 경우, realloc() 함수는, 지정한 사이즈의 malloc() (와)과 같은 움직임을 합니다.

reallocf() 함수는, 요구된 메모리를 할당할 수가 없었던 경우에, 건네받은 포인터를 해방하는 것을 제외하면, realloc() 함수 호출과 같습니다. 이것은 FreeBSD 에 고유의 API 로, realloc() 의 종래형의 코딩 스타일을 이용하면(자), 프로그램 라이브러리의 내부에서 메모리 리크를 일으킨다고 한다 문제를 없애기 위해서(때문에) 설계되었습니다.

free() 함수는, ptr 그리고 참조되는 할당 끝난 메모리를 향후의 할당을 위해서(때문에) 사용할 수 있도록(듯이) 합니다. ptr 하지만 NULL 인 경우, 아무것도 실행되지 않습니다.

조정
이러한 메모리 할당 routine군의 1 개가 처음으로 불려 갈 때, 이 할당 실행의 동작에 영향을 준다 다양한 플래그가 세트 혹은 리셋트 됩니다.

/etc/malloc.conf 그렇다고 하는 기호 연결로 참조되는 파일의 「명칭」, 환경 변수 MALLOC_OPTIONS 의 값, 글로벌 변수 malloc_options 하지만 가리키는 캐릭터 라인은, 이 순서로 1 캐릭터마다 플래그로서 해석됩니다.

대부분의 플래그는 1 캐릭터로, 대문자는 동작이 설정된 것, 즉 온이 되어 있는 것을 나타내, 소문자는 동작이 설정되어 있지 않은 것, 즉 오프가 되어 있는 것을 나타냅니다.

A   모든 경고 (이해할 수 없는 플래그가 설정되어 있다고 하는 경고를 제외하다)(을)를 치명적 에러로 합니다. 이 경우, 프로세스는 abort(3) (을)를 호출합니다.

J   malloc(), realloc(), reallocf() 에 할당할 수 있는 신규의 메모리, 똑같이 free(), realloc(), reallocf() 그리고 돌려주어지는 메모리의 각 바이트를 0xd0 에 초기화합니다. 이 옵션은 “R” 옵션도 세트 합니다. 이것은 디버그용의 옵션으로, 퍼포먼스의 저하에 강한 영향을 줍니다.

H   할당 함수로 사용되지 않은 페이지에 관한 힌트를 커널에게 줍니다. 시스템이 과도하게 페이징을 실시하고 있는 경우는, 퍼포먼스가 향상합니다. 이 옵션은, 디폴트로 오프가 되어 있습니다.

R   최초의 할당이 충분히 큰 경우여도, realloc() 함수와 reallocf() 함수가 항상 메모리의 재할인 맞히고를 하게 됩니다. 메모리를 압축하는 경우의 큰 도움이 됩니다.

U   모든 오퍼레이션으로, ktrace(1) (을)를 위한 “utrace” 엔트리를 생성합니다. 이 옵션의 상세한 것에 대하여는, 소스를 참조해 주세요.

V   0 바이트를 할당하려고 했을 때에, 유효한 포인터 대신에 NULL 포인터가 돌려주어지게 됩니다 (디폴트의 동작에서는, 최소의 할당을 실시해, 그 포인터를 돌려줍니다). 이 옵션은 System V 와의 호환성을 위해서(때문에) 제공되고 있습니다. 이 옵션은 “X” 옵션과 적합하지 않습니다.

X   할당 함수로 에러를 돌려주는 대신에, 진단 메세지를 stderr 에 표시해, ( abort(3) (을)를 사용해) 프로그램을 core 에 떨어뜨립니다. 이 옵션은, 컴파일시에, 원시 코드에 이하를 짜넣도록(듯이) 해 설정해야 합니다.

        extern char *malloc_options;
        malloc_options = "X";

Z   이 옵션을 설정하면(자), “J” 옵션과 “R” 옵션이 설정되어 요구된 바이트열에 0 이 출력됩니다. 이것은 디버그용의 옵션으로, 퍼포먼스의 저하에 강한 영향을 줍니다.

<   캐쉬 사이즈를 2 분의 1 으로 합니다. 디폴트의 캐쉬 사이즈는 16 페이지입니다. 이 옵션은 여러 차례 지정할 수 있습니다.

>   캐쉬 사이즈를 2 배로 합니다. 디폴트의 캐쉬 사이즈는 16 페이지입니다. 이 옵션은 여러 차례 지정할 수 있습니다.

“J” 옵션과 “Z” 옵션은, 테스트와 디버그용입니다. 이러한 옵션을 사용하고 있을 때 동작이 바뀌는 어플리케이션에는 결함이 있습니다.

사용예
캐쉬 사이즈를 시스템 전체로 작게 해, 문제가 발생했을 경우는 항상 코어덤프를 취하는 것 같은 설정은,

    ln -s 'A<' /etc/malloc.conf

프로그램이 이러한 함수의 소환시에 반환값을 체크하지 않는 것을 소스로 명시하려면 ,

    extern char *malloc_options;
    malloc_options = "X";

환경 변수
이하의 환경 변수는, 메모리 할당 함수의 실행에 영향을 줍니다.

MALLOC_OPTIONS
    환경 변수 MALLOC_OPTIONS (을)를 설정하면(자), 이 환경 변수에 포함되는 캐릭터는, 메모리 할당 함수군의 플래그로서 해석됩니다.

반환값
malloc() 함수와 calloc() 함수는, 성공했을 경우는 할당할 수 있었던 메모리에의 포인터를 돌려주어, 그 이외의 경우는 NULL 포인터를 돌려주어 errno (을)를 ENOMEM (으)로 설정합니다.

realloc() 함수와 reallocf() 함수는, 성공했을 경우는 혹시 ptr (와)과 동일한, 할당할 수 있었던 메모리에의 포인터를 돌려줍니다. 그 이외의 경우는 NULL 포인터를 돌려줍니다. 그 경우에서도 ptr 에 의해 참조되는 메모리는 이용 가능해 그대로 남습니다. 메모리의 할당해에 실패했을 경우는, errno (을)를 ENOMEM (으)로 설정합니다.

free() 함수는 값을 돌려주지 않습니다.

MALLOC 의 문제의 디버그
이 실장은, 할당할 수 있지 않은 한 해방되고 있는 페이지는 액세스 되지 않고, 재이용을 위해서(때문에) 커널에 적극적으로 돌려주어진다고 하는 점이, 외 (의 시스템)의 메모리 할당의 실장과 크게 다릅니다.

대부분 (의 시스템)의 메모리 할당의 실장에서는, 린크드리스트를 포함한 데이터 구조가, 해방되고 있는 메모리의 덩어리안에 보존되어 해방 떠날 수 있어 모든 메모리를 서로 결합하기 위해서 사용됩니다. 해방 리스트를 왕래할 때마다, 미사용의, 페이지 아웃 되고 있을 페이지가, 프라이마리메모리에 들어가기 위해서(때문에) 페이지 폴트를 일으키기 (위해)때문에, 이것은 최적이다고는 말할 수 없습니다. 페이징을 실시하는 시스템에서는, 1 개의 프로세스에 의해 생기는 페이지 폴트의 수가 5 배에 증가하는 결과가 되는 일이 있습니다.

이 아키텍쳐에는, 지금까지는 검출되지 않았던 인터페이스의 세들로 한 위반이, 실제로 검출되게 된다고 하는 부작용이 있습니다. 이 때문에, 훨씬 문제 없게 움직이고 있던 프로그램이, 이 할당의 실장과 링크 하자 마자 문제가 속출하는 일이 있습니다.

최초로 해야 할 일, 그리고 가장 중요한 (일)것은 “A” 옵션을 설정하는 것입니다. 이 옵션을 설정하면(자), 가능한 한 처리를 계속하려고 하는 통상의 방침을 취하는 대신에, 문제가 발생했을 때에 (가능하면) 코어덤프를 강제적으로 취합니다.

디버거의 서포트를 위해서(때문에), 적절한 옵션과 심볼로 프로그램을 재컴파일 하는 것이 아마 현명합니다.

프로그램이, 통상과는 다른 결과를 내거나 코어덤프 하거나 다음의 섹션으로 드는 것 같은 메세지를 보내지 않고 다른 동작을하기 시작하는 것 같은 경우는, 프로그램이 0 의 바이트로 채워지고 있는 기억 area에 의존하고 있는 경우라면 생각됩니다. “Z” 옵션을 설정해 실행해 보세요. 상황이 호전되었을 경우는, 이 진단이 올발랐던 것이 됩니다. 이것이라도 프로그램이 이상한 동작을 하는 것 같으면, 할당할 수 있었던 area 이외의 메모리, 대체로는 할당할 수 있었던 area의 전방은 아니고 후방에 액세스 한다고 하는 문제라면 생각됩니다.

혹은, 증상이 용이하게 재현하지 않는 경우는, “J” 옵션을 설정하면(자) 문제를 일으키는 도움이 될지도 모릅니다.

정말로 어려운 상황에서는, 커널로 “U” 옵션이 서포트되고 있는 경우는 그것을 설정하면(자), 이러한 함수의 모든 소환의 상세한 트레이스가 작성됩니다.

공교롭게도, 이 실장에서는, 검출된 문제에 관한 자세한 것은 제공되지 않습니다. 그러한 정보를 보존하는 것으로, 퍼포먼스가 악영향을 받기 (위해)때문입니다. 퍼포먼스와 교환에 한층 더의 건전함의 체크와 상세한 진단을 실시해, 문제의 검출과 위치의 특정에 초점을 맞힌 수많은 메모리 할당의 실장이, 인터넷으로 이용 가능합니다.

진단 메세지
malloc(), calloc(), realloc(), free() 하지만 에러나 경고를 검출하면(자), 메세지가 파일 기술자 STDERR_FILENO 에 출력됩니다. 에러의 경우, 프로세스는 코어덤프 합니다. “A” 옵션을 설정하면(자), 모든 경고는 에러로서 다루어집니다.

이하에서는, 출력될 가능성이 있는 에러 메세지와 그 의미에 대해 간단하게 설명합니다.

(ES): mumble mumble mumble “EXTRA_SANITY” 하지만 정의된 상태로 메모리 할당 함수가 컴파일 되고 있어 상세한 에러 체크중에 에러가 검출되었습니다. 상세한 것에 대하여는, 원시 코드를 참조해 주세요.

mmap(2) failed, check limits 시스템이 위험한 과부하인 상태인지, 프로세스의 제한이 올바르고 지정되어 있지 않다고 생각됩니다.

freelist is destroyed 내부의 해방 리스트가 망가져 있습니다.

out of memory “X” 옵션이 지정되어 있어, 한편, 메모리의 할당해에 실패했습니다.

이하에서는, 출력될 가능성이 있는 경고 메세지와 그 의미에 대해 간단하게 설명합니다.

chunk/page is already free 벌써 해방되고 있는 메모리를 free() 그리고 해방하려고 했습니다.

junk pointer, ... 메모리 할당 함수에게 줄 수 있었던 포인터가, 인식되고 있는 메모리 경계의 외측을 가리키고 있습니다.

malloc() has never been called 메모리가 할당해지지 않은에도 불구하고, 해방하려고 하거나 재할인 맞히고 하려고 했습니다.

modified (chunk-/page-) pointer free() 인가 realloc() 에게 건네진 포인터를 고쳐 쓸 수 있고 있습니다.

pointer to wrong page realloc(), free() 혹은 reallocf() 하지만 해방하려고 하고 있는 포인터가, 올바른 페이지를 참조하고 있지 않습니다.

recursive call 메모리 할당 함수를 재귀적으로 호출하려고 했습니다. 이것은 허가되고 있지 않습니다. 특히 시그널 핸들러에서는, 메모리의 할당을 해야 하는 것이 아닙니다.

unknown char in MALLOC_OPTIONS 불명한 옵션이 지정되었습니다. “A” 옵션을 설정해 있어도, 이 경고는 단순한 경고로서 다루어집니다.

관련 항목
brk(2), mmap(2), alloca(3), getpagesize(3), memory(3) /usr/share/doc/papers/malloc.ascii.gz

표준
malloc(), calloc(), realloc(), free() 함수는 isoC 에 적합하고 있습니다.

역사
현재의 메모리 할당의 실장은, 개별의 게르마늄 트랜지스터로 작성된, 20 비트 바이너리 컴퓨터에 장착된 드럼의 파일 시스템으로서 스타트 했습니다. 그 이후는, 2차 보존역이 아니고, 일차 보존역을 조작하게 되었습니다. 이 새로운 형태와 기능은 FreeBSD 2.2 그리고 처음 등장했습니다.

reallocf(3) 함수는 FreeBSD 3.0 그리고 처음 등장했습니다.

저자
Poul-Henning Kamp <phk@FreeBSD.org>

버그
문제가 발생했을 경우에 출력되는 메세지는, 실제의 값에 대한 상세를 제공하지 않습니다.

0 바이트를 할당하도록(듯이) 요구되었을 경우에 NULL 포인터를 돌려주는 것은, 어리석은 질문에 대한 어리석은 반응이다고 말할 수 있습니다.