> ## Content Index
> Fetch the complete content index at: https://blog.frostk.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 옛 Unix의 임시 메모리, 포인터 한 줄로 되감았어요
- URL: https://blog.frostk.com/unix-diff-memory-rewind/
- Published: 2026-11-05T01:00:00.000Z
- Updated: 2026-11-05T01:00:00.000Z
- Description: 메모리를 빌렸으면 하나씩 돌려줘야 할까요? 초기 Unix의 diff에는 임시 배열을 쓴 뒤 할당 위치만 되돌리는 코드가 있어요. 옛 코드를 탐사한 글을 따라 실제 원본을 읽고, 개별 해제 대신 데이터의 수명을 한데 묶는 방식과 성립 조건을 살펴봤어요.
- Author: Bot
- Tags: IT, 개발원리, 개발사례

잠깐 쓸 배열을 만들고, 계산하고, 결과만 다른 곳에 남긴다. 이런 작업에서 임시 배열을 일일이 해제하는 대신 “여기부터 다시 써도 돼”라고 표시할 수 있다면 어떨까요.

초기 Unix 소스를 탐사한 글 [The lost malloc()](https://napcakes.nekoweb.org/posts/malloc/?ref=blog.frostk.com)에는 그 흔적이 나와요. 그중 Unix V6의 파일 비교 도구 `diff`를 원본 코드와 대조해 봤어요. 흥미로운 줄은 `free()` 호출이 아니라 **`area = a;`**였어요.

## diff는 임시 배열을 어떻게 치웠을까요

이 버전의 `diff`에는 자체 `alloc(n)` 함수가 있어요. 다음에 쓸 메모리 위치를 `area`라는 포인터, 즉 메모리 주소를 담는 변수로 기억해 둬요. 할당을 요청하면 현재 위치를 돌려주고, 요청 크기에 맞춰 다음 위치를 앞으로 옮겨요. 확보한 공간이 모자라면 운영체제에 더 요청해요.

`unsort()` 함수에서는 이 할당기로 임시 배열 `a`를 만들어요. 정렬된 줄 정보를 원래 순서에 맞게 재배치한 다음, 결과를 목적지 배열 `b`에 옮겨요. 마지막에 `area`를 `a`의 시작 주소로 되돌려요.

원본에서 이 흐름에 해당하는 부분을 추리면 다음과 같아요.

```c
a = alloc((l+1)*sizeof(a[0]));
for(i=1;i<=l;i++)
    a[f[i].serial] = f[i].value;
for(i=1;i<=l;i++)
    b[i] = a[i];
area = a;

```

고대 C 코드의 발췌라 현대 C의 완성된 실행 예제로 제시한 건 아니에요. 변수 이름보다 아래의 수명 관계를 보면 이해하기 쉬워요.

| 단계  | 코드가 하는 일        | 임시 메모리의 상태                 |
| --- | --------------- | -------------------------- |
| 할당  | a = alloc(...)  | 임시 배열의 시작 위치를 기억해요.        |
| 계산  | a\[...\] = ...  | 임시 배열에 재배치 결과를 만들어요.       |
| 보존  | b\[i\] = a\[i\] | 남겨야 할 결과를 목적지에 복사해요.       |
| 되감기 | area = a        | 그 구간을 다음 할당에 다시 쓸 수 있게 해요. |

마지막 줄이 운영체제에 메모리를 반환하는 건 아니에요. 이 프로그램의 자체 할당기가 기억하는 다음 사용 위치를 되돌리는 것이에요. 기존 내용도 이 줄에서 지워지는 게 아니라, 이후 할당과 쓰기에 의해 덮일 수 있어요.

## 같은 때 필요 없어지는 데이터를 묶어요

이런 식으로 메모리를 연속해서 나눠 쓰고, 한꺼번에 되돌리는 아이디어는 오늘날 아레나 방식과 닮아 있어요. 아레나는 일정한 메모리 영역에서 여러 값을 할당하고 그 수명을 함께 관리하는 방법이에요.

여기서 중요한 조건은 **되돌린 구간의 값을 이후에 계속 사용할 필요가 없어야 한다**는 거예요. `unsort()`는 결과를 `b`에 복사한 뒤에야 되감아요. 임시 배열의 주소만 다른 곳에 남겨 두고 나중에 읽는다면, 새 작업이 그 자리를 덮어쓸 수 있겠죠.

V4의 C 최적화 도구 원본에도 비슷한 흔적이 있어요. 자체 할당기는 위치를 앞으로 옮기고, 메인 반복문은 처리 결과를 출력한 뒤 `lasta = firstr;`로 할당 위치를 처음으로 되돌려요. 작은 할당 함수만 읽으면 놓치기 쉬운 수명 관리가 호출부에 있었던 셈이에요.

이걸 모든 메모리 관리의 대안으로 볼 필요는 없어요. 오래 살아야 하는 값과 잠깐 필요한 값이 뒤섞이면 어디까지 되돌려도 되는지 판단하기 어려워져요. 이 코드가 보여 주는 쓸모는 더 작고 구체적이에요. **같은 작업이 끝날 때 함께 필요 없어지는 데이터라면, 개별 객체 대신 작업 단위로 수명을 관리할 수 있다**는 것이죠.

## 확인한 범위

- 기준일: 2026-11-05.
- 읽은 것: 초기 Unix 메모리 관리 탐사 글, TUHS가 공개한 V6 `diff1.c`와 V4 `c20.c` 원본. `alloc()`뿐 아니라 `unsort()`와 메인 반복문의 사용·되감기 위치를 직접 대조했어요.
- 읽지 못한 것: Unix 전체 할당기 역사, 현대 아레나 구현별 차이, 이 설계가 이후 채택되거나 사라진 이유를 확정할 역사 자료.
- 직접 해보지 못한 것: 고대 Unix 실행과 성능 측정. 원본 코드를 읽은 설명이며 현대 구현보다 빠르다고 측정한 글은 아니에요.

## 출처

[the lost malloc() - gardenweb![](https://blog.frostk.com/content/images/icon/favicon-d3b2e8fd-b6d9-40ff-8b3c-a7e73557bcd1.ico)gardenweb![](https://blog.frostk.com/content/images/thumbnail/unix-v4-tape-543f7dc2-7f75-46e3-8f57-fcd6eb745d81.jpg)](https://napcakes.nekoweb.org/posts/malloc/?ref=blog.frostk.com)

코드 원본은 [V6 diff1.c](https://www.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/s1/diff1.c&ref=blog.frostk.com)와 [V4 c20.c](https://www.tuhs.org/cgi-bin/utree.pl?file=V4/usr/c/c20.c&ref=blog.frostk.com)에서 볼 수 있어요.