[CSAPP] 9.9 Dynamic Memory Allocation 9.9.1~9.9.2

JunHyeok Kim·2024년 4월 24일
0

9.9 Dynamic Memory Allocation

While it is certainly possible to use the low-level mmap and munmap functions to create and delete areas of virtual memory, C programmers typically find it more convenient and more portable to use a dynamic memory allocator when they need to acquire additional virtual memory at run time.

mmap 이나 munmap 보다는 동적 메모리 할당기를 사용하여 좀 더 편리하고 호환성 좋게 동적 메모리 할당이 가능해 보입니다.

A dynamic memory allocator maintains an area of a process’s virtual memory known as the heap (Figure 9.33). Details vary from system to system, but without loss of generality, we will assume that the heap is an area of demand-zero memory that begins immediately after the uninitialized data area and grows upward (toward higher addresses). For each process, the kernel maintains a variable brk (pronounced “break”) that points to the top of the heap.

동적 메모리 할당기는 힙 이라고 하는 프로세스의 가상 메모리 영역을 관리합니다.
일반론적으로, 힙은 .bss 영역 위에서부터 시작해서 brk 영역까지 위쪽으로 확장합니다.

An allocator maintains the heap as a collection of various-size blocks. Each block is a contiguous chunk of virtual memory that is either allocated or free. An allocated block has been explicitly reserved for use by the application. A free block is available to be allocated. A free block remains free until it is explicitly allocated by the application. An allocated block remains allocated until it is freed, either explicitly by the application or implicitly by the memory allocator itself.

동적 메모리 할당기는 힙을 다양한 사이즈의 블록 집합으로 관리합니다. 각각의 블록은 할당됐거나, 비어있는 가상 메모리의 연속적인 묶음. 할당된 블록은 프로그램이 사용하기 위해 명시적으로 보존된 것 입니다.
free block(할당되지 않은 블록)은 프로그램에 의해 명시적으로 할당되기 전 까지 free 상태로 있습니다. 또한 할당된 메모리는 프로그램에 의해 명시적으로 free가 되거나, 할당기에 의해 묵시적으로 반환 될 때 까지 할당된 채로 남아있습니다.

Explicit allocators

It require the application to explicitly free any allocated blocks. For example, the C standard library provides an explicit allocator called the malloc package. C programs allocate a block by calling the malloc

명시적 할당기는 프로그램이 명시적으로 할당된 블록을 Free 해 줄 것을 요구합니다. C에서 malloc()과 free()에 해당합니다!

Implicit allocators

on the other hand, It require the allocator to detect when an allocated block is no longer being used by the program and then free the block. Implicit allocators are also known as garbage collectors, and the process of automatically freeing unused allocated blocks is known as garbage collection. For example, higher-level languages such as Lisp, ML, and Java rely on garbage collection to free allocated blocks.

묵시적 할당기는, 프로그램이 더 이상 할당된 블록이 사용되지 않는다고 판단하면 free를 해줍니다. 묵시적 할당기로는 가비지 콜렉터가 있습니다. 자바의 GC가 대표적이죠!

The remainder of this section discusses the design and implementation of explicit allocators. We will discuss implicit allocators in Section 9.10. For concreteness, our discussion focuses on allocators that manage heap memory. However, you should be aware that memory allocation is a general idea that arises in a variety of contexts. For example, applications that do intensive manipulation of graphs will often use the standard allocator to acquire a large block of virtual memory and then use an application-specific allocator to manage the memory within that block as the nodes of the graph are created and destroyed.

우리의 논의는 힙 메모리를 관리하는 할당기에 집중할 것이다. 그러나 메모리 할당이 여러 가지 문맥에서 일어나는 일반적인 아이디어라는 점을 알고 있어야 합니다!

9.9.1 The malloc and free Functions

The C standard library provides an explicit allocator known as the malloc package. Programs allocate blocks from the heap by calling the malloc function.

C 표준 라이브러리는 malloc 패키지 라는 명시적 할당기를 제공합니다.

malloc

The malloc function returns a pointer to a block of memory of at least size bytes that is suitably aligned for any kind of data object that might be contained in the block. In practice, the alignment depends on whether the code is compiled to run in 32-bit mode (gcc -m32) or 64-bit mode (the default). In 32-bit mode, malloc returns a block whose address is always a multiple of 8. In 64-bit mode, the address is always a multiple of 16.

말록 펑션은 적절히 정렬된 어떤 타입의 데이터 오브젝트의 주솟값을 반환합니다.사실, 정렬은 시스템의 비트에 따라 다르게 됩니다. 32비트에서는 malloc 주소가 항상 8의 배수이며 64비트에서는 16배수 입니다.

If malloc encounters a problem (e.g., the program requests a block of memory that is larger than the available virtual memory), then it returns NULL and sets errno. Malloc does not initialize the memory it returns. Applications that want initialized dynamic memory can use calloc, a thin wrapper around the malloc function that initializes the allocated memory to zero. Applications that want to change the size of a previously allocated block can use the realloc function.

malloc에서 문제가 생기면 (예를 들어, 프로그램이 가용 가능한 가상메모리를 넘어선 블록의 메모리를 요청한 경우), NULL을 리턴하고 errno을 설정합니다.
malloc은 리턴하는 메모리를 초기화 하지 않습니다. 초기화한 동적 메모리를 원하면 calloc을 사용할 수 있는데, 이것은 할당된 메모리를 0으로 초기화하는 calloc 함수 주위의 얇은 래퍼 함수이다(그냥 래퍼함수).

  1. mmap은 Memory Mapping 을 위한 system call 중 하나입니다.
  2. munmap 은 Memory unMapping을 위한 system call 중 하나입니다.

sbrk

The sbrk function grows or shrinks the heap by adding incr to the kernel’s brk pointer. If successful, it returns the old value of brk, otherwise it returns −1 and sets errno to ENOMEM. If incr is zero, then sbrk returns the current value of brk. Calling sbrk with a negative incr is legal but tricky because the return value (the old value of brk) points to abs(incr) bytes past the new top of the heap.
Programs free allocated heap blocks by calling the free function.

sbrk (Set Break) 함수는 incr 증감자로 커널의brk 포인터를 변화시킵니다. 성공하면 이전의 brk 값을 리턴하고, 아니면 -1을 리턴하고 errono을 ENOMEM으로 설정합니다. 만일 incr 값이 0이면, Set Break 함수는 현재 brk값을 리턴합니다.

free

The ptr argument must point to the beginning of an allocated block that was obtained from malloc, calloc, or realloc. If not, then the behavior of free is undefined. Even worse, since it returns nothing, free gives no indication to the application that something is wrong. As we shall see in Section 9.11, this can produce some baffling run-time errors.

ptr 매개변수는 반드시 malloc, calloc, realloc으로 인해 할당된 포인터 주소여야 합니다. 그렇지 않으면, free 함수의 동작은 정의되지 않습니다. free는 아무것도 리턴하지 않기 때문에 무엇인가 질못 된 것을 응용 프로그램에 알릴 수가 없습니다.

(a)
프로그램은 4워드 블록을 요청한다.
(b)
프로그램은 5워드 블록을 요청한다. 가용 블록의 앞부분에서 정렬되게 할 수 있도록 6워드 블록을 할당한다.
(c)
프로그램은 6워드 블록을 요청한다.
(d)
b 에서 할당된 6워드 블록을 반환해준다. free를 해줌에도 불구하고 포인터 p2는 여전히 해당 주소를 가르키고 있다. p2가 새로운 malloc에 의해 다시 초기화 될 때 까지 p2를 사용하지 않는 것은 프로그래머의 책임이다!
(e)
p4에 2워드 블록을 요청한다.

9.9.2 Why Dynamic Memory Allocation?

The most important reason that programs use dynamic memory allocation is that often they do not know the sizes of certain data structures until the program actually runs. For example, suppose we are asked to write a C program that reads a list of n ASCII integers, one integer per line, from stdin into a C array. The input consists of the integer n, followed by the n integers to be read and stored into the array. The simplest approach is to define the array statically with some hard-coded maximum array size:

프로그램이 구동 될 때 까지 데이터의 사이즈를 알 수 없기 때문에 동적 할당이 필요합니다. 예를 들어, n개의 ASCII 정수의 리스트를 라인마다 한 개의 정수씩 C 배열로 읽는 프로그램을 작성한다고 가정해보자. 입력은 정수n과 배열에 저장해야하는 n개의 정수로 구성된다.

백준 문제처럼 배열의 최댓값이 정해진 것이 아니라면, 배열의 크기를 변경할 때 마다 컴파일하고 재실행을 해야 할 것이다. 따라서 아래와 같이 동적으로 크기를 할당할 수 있다.

0개의 댓글