[Malloc Lab-2] CSAPP 9.9 동적 메모리 할당 (0) : 들어가며

은채·2025년 4월 24일

Malloc Lab

목록 보기
2/21
post-thumbnail

Malloc Lab 프로젝트를 위해서는 CSAPP의 9.9의 동적 메모리 할당 부분을 꼼꼼히 읽고 이해해야 합니다.
9.9 동적 메모리 할당 부분은 총 14개의 소단원으로 나누어져 있습니다.
한 게시글에 하나의 소단원을 다루려고 합니다.

CSAPP 책은 쌩으로 읽는다면 이해하기 매우 어렵습니다.
따라서 소단원만 그대로 따라가되, 내용을 이해하기 쉽게 재구성했습니다.

9.9.0 동적 메모리 할당 - 들어가며

프로그램 실행 이후에 더 많은 메모리가 필요해지는 순간이 있다.
예로, 사용자 입력을 받거나 동적으로 배열을 늘려야 할 경우이다.
이럴 때 정적으로 선언된 배열만으로는 한계가 있다.

그렇다면 실행 중에는 메모리를 어떻게 확보할 수 있을까?
동적으로 메모리를 할당하는 방법을 알아보자.

1. 동적으로 메모리를 할당하는 두 가지 방법

C에서 이 문제를 해결하기 위한 두 가지 대표적인 방법이 있다.

1) mmap, munmap 함수 사용하기

가장 저수준의 방식이다.
운영체제가 제공하는 mmap, munmap 함수를 사용해 메모리 영역을 직접 관리할 수 있다.

  • mmap: 새로운 메모리 영역을 생성할 때 사용하는 함수
  • munmap: mmap으로 생성한 메모리 영역을 해제할 때 사용하는 함수이다.

복잡하고 시스템 종속적인 코드가 될 수 있어 C 프로그래머들은 잘 사용하지 않는 방식이다.

2) 동적 메모리 할당기 사용하기

대부분의 C 프로그래머들은 동적 메모리 할당기를 사용한다.
동적 메모리 할당기는 malloc, calloc, realloc, free 같은 함수들로 구성된 표준 라이브러리 함수들이다.

mmap 방식보다 훨씬 편리하고 호환성이 뛰어나다.
동적 메모리 할당기는 힙(heap)에 메모리를 저장하는데, 힙은 실행 중에도 메모리를 동적으로 할당받는다.

2. 힙의 구조

힙은 실행 중 동적으로 할당된 메모리들이 저장되는 공간이다.
stack과는 반대로, 프로그램 실행 중에 크기가 바뀔 수 있다.

아래는 힙(heap)의 일반적인 구조를 나타낸 그림이다.

힙은 초기화되지 않은 데이터 영역(.bss) 바로 다음에서 시작해서 위쪽으로 자란다.
즉, 낮은 주소에서부터 높은 주소 방향으로 커진다.

힙은 demand-zero memory(메모리를 요청하면 0으로 초기화된 페이지를 즉시 제공하는 OS의 기능)이다.
demand-zero memory 덕분에 힙에 메모리가 요청될 때마다 비어 있는 공간을 0으로 채워서 준다.

각 프로세스마다 커널은 힙의 끝을 가리키는 포인터brk를 사용한다.
메모리 요청이 들어오면 brk를 늘려 새로운 메모리를 제공한다.

3. 힙의 블록

힙은 여러 크기의 블록으로 구성되며, 각 블록은 1) 할당되거나 2) 비어있는 상태이다.

1) 할당된 블록 (Allocated Block)

프로그램이 명시적으로 요청해서 확보한 메모리이다.
프로그램이 직접 free를 호출하거나, Garbage Collector가 동작하기 전까지 계속 유지된다.

2) 비어있는 블록 (Free Block)

아직 사용되지 않은 블록이다.
나중에 malloc 요청이 들어오면 이 블록을 할당해줄 수 있다.

이런 블록들은 마치 퍼블 조각처럼 메모리 상에 이어져 있으며, 할당기(allocator)가 이들을 잘게 쪼개고 병합하며 관리한다.

명시적 할당기 vs. 암묵적 할당기

할당기에는 명시적 할당기암묵적 할당기, 두 가지 기본 형태가 있다.
둘 다 할당은 명시적으로 malloc 등으로 하지만, 할당된 블록을 누가 해제(free)하느냐에 따라서 구분된다.

1) 명시적 할당기 (Explicitly Allocator)

프로그래머가 직접 free()를 호출하여 메모리를 해제한다.

  • C: mallocfree
  • C++: newdelete

2) 암묵적 할당기 (Implicit Allocator / Garbage Collector)

사용자가 더 이상 사용하지 않는 메모리를 자동으로 감지하여 해제하는 방식이다.
free()를 직접 하지 않아도 된다.
Garbage Collector(GC)라고도 불리며, 이 과정은 Garbage Collection이라고 한다.

  • Lsip, ML, Java, Python 등 고급 언어

0개의 댓글