힙 메모리 할당
힙 : 프로세스의 초기화되지 않은 데이터 세그먼트 바로 뒤에서 시작하는 가변 크기 세그먼트로, 연속되 가상 메모리로 이뤄져 있으며, 메모리가 할당되고 해제됨에 따라 자라고 줄어든다.
프로그램 브레이크 : 힙의 현재 한도
#include <stdlib.h>
int brk(void *end_data_segment) : 성공하면 0을 리턴하고, 에러가 발생하면 -1을 리턴
- 프로그램 브레이크를 end_data_segment 가 가리키는 위치로 설정, 가상 메모리는 페이지 단위로 할당되므로, end_data_segment는 실제로는 다음 페이지 경계로 올림된다.
void *sbrk(intptr_t increment) : 성공하면 0을 리턴하고, 에러가 발생하면 (void *) -1을 리턴
- 프로그램 브레이크를 increment 만큼 증가시킨다. 성공하면 프로그램 브레이크의 이전 주소를 리턴한다. sbrk(0) 호출은 프로그램 브레이크의 현재 값을 바꾸지 않고 그대로 리턴한다.
malloc() 과 free()의 장점
1. C언어의 일부로 표준화되어 있다.
2. 멀티스레드 프로그램에서 쓰기 쉽다.
3. 작은 단위로 메모리를 할당하는 간단한 인터페이스를 제공한다.
4. 임의로 메모리 블록을 해제할 수 있다. 해제된 메모리 블록은 프리 리스트로 관리되어 추후 메모리 할당 시 재활용된다.
#include <stdlib.h>
void *malloc(size_t size) : 성공하면 할당된 메모리를 가리키는 포인터를 리턴하고, 에러가 발생하면 NULL을 리턴
- void*를 리턴하기 때문에 어떤 현의 C포인터에도 대입할 수 있다.
void free(void *ptr)
- 프로그램 브레이크를 낮추지 않고, 해당 메모리 블록을 이후의 malloc() 호출 때 재활용할 프리 블록 리스트에 추가한다.
* 할당된 포인터를 두번 free 해제하면 예측할 수 없는 에러를 야기할 수 있다.
malloc 디버그 도구와 라이브러리
1. mtrace(), muntrace() 함수를 통해 메모리 할당 호출 추적 기능을 켜거나 끌 수 있다. 이 함수는 환경 변수 MALLOC_TRACE와 함께 쓰이는데, 이 환경 변수에는 추적 정보를 저장할 파일이름이 정의된다.
2. mcheck(), mprobe() 함수를 통해 할당된 메모리 블록에 대해 일관성 점검을 수행할 수 있다. 예를 들어, 할당된 메모리 블록 바깥에 쓰려고 하는 등의 에러를 잡을 수 있다. (cc -lmcheck 옵션을 통해 mcheck 라이브러리와 링크돼야 함)
3. MALLOC_CHECK_ 환경 변수는 mcheck(),mprobe() 와 비슷한 기능을 수행한다. (차이점은 컴파일이 필요없음)
#include <stdlib.h>
void *calloc(size_t numitems, size_t size) : 성공하면 할당된 메모리를 가리키는 포인터를 리턴하고, 에러가 발생하면 NULL을 리턴
- numitems는 할당할 항목의 개수를 지정하고, size 는 각 항목의 크기를 지정한다. malloc()과 달리 할당된 메모리를 0으로 초기화한다.
void *realloc(void *ptr, size_t size) : 성공하면 할당된 메모리를 가리키는 포인터를 리턴하고, 에러가 발생하면 NULL을 리턴
- ptr은 크기를 변경할 메모리 블록을 가리키는 포인터다. size는 블록의 새 크기를 지정한다.
둘 다 free 로 해제해야 한다.
스택에 메모리 할당
#include <alloca.h>
void *alloca(size_t size) : 할당된 메모리 블록을 가리키는 포인터를 리턴
- size 는 할당할 바이트 수를 지정한다.
malloc 패키지 함수와 마찬가지로, alloca()는 동적으로 메로리를 할당한다. 하지만 힙에서 메모리를 구하는 대신, alloca()는 스택 프레임의 크기를 증가시킴으로써 스택에서 메모리를 구한다.
alloca() 때문에 스택오버플로가 발생하면, 프로그램의 동작을 예측할수 없게 된다. 특히 에러를 알리는 NULL 리턴값을 받지 못한다.
장점은 메모리 블록 할당속도가 malloc() 보다 빠르다. 컴파일러가 alloca()를 택 포인터를 직접 조정하는 인라인 코드로 구현하기 때문이다. 그리고 프리 블록 리스트를 관리할 필요가 없다. 자신을 호출한 함수가 리턴하면 자동으로 해제된다.
'리눅스' 카테고리의 다른 글
[리눅스 API] 프로세스 자격증명 (0) | 2015.08.06 |
---|---|
[리눅스 API] 사용자와 그룹 (0) | 2015.08.05 |
[리눅스] 파일시스템 (0) | 2015.07.31 |
[리눅스 API] 프로세스 (0) | 2015.07.27 |
윈도우 이클립스 gcc 컴파일 (0) | 2015.07.27 |
댓글