1973년 Unix V4에 숨어 있던, 오늘날보다 나은 malloc()
The lost malloc()
1973년 Unix V4 소스에서 Dennis Ritchie가 작성한 malloc.c를 들여다보면, 오늘날의 malloc()/free()와 달리 메모리 영역을 명시적으로 넘겨받는 인터페이스가 등장한다. coremap과 swapmap을 인자로 받아 영역별로 할당·해제하고, mfree()는 해제할 크기까지 받는다. 저자는 이 설계가 힙 손상 문제를 줄이고 서드파티 메모리를 통째로 회수할 수 있는, 지금보다 나은 인터페이스였다고 평가한다. V4 테이프는 2024년에야 발견됐다.
이 함수들은 명시적인 메모리 영역 위에서 동작한다! 게다가 mfree()는 해제하는 객체의 크기를 인자로 받는데, 당연히 그래야 한다. 이는 전통적인 malloc()/free()보다 무한히 나은 인터페이스다.
HN 토론
42- adrian_b
작성자는 SIMULA 67이 "new"를 어디서 가져왔는지 정말로 찾아내지 못했다.
1965년 11월, C.A.R. Hoare는 매우 영향력 있는 논문 "Record Handling"을 발표했다. 이는 ALGOL 60의 후속 언어를 위한 제안된 확장이었다.
SIMULA 67에서 전신인 SIMULA 언어에 비해 추가된 거의 모든 기능은 Hoare의 논문에서 직접 나온 것이며, 두 가지 큰 예외가 있다: 클래스 상속과 "가상" 프로시저인데, 이는 SIMULA 67 창시자들(Kristen Nygaard & Ole-Johan Dahl)이 발명한 것으로 객체 지향 프로그래밍에 필수적이다.
SIMULA 67의 키워드 "class"와 "new"는 Hoare의 논문에서 가져온 것이다(Hoare는 실제로 "class"를 COBOL 60에서 가져왔는데, COBOL 60은 ALGOL 60과 비교할 때 매우 다른 용어를 사용했으며, 여러 차이점 중 하나는 ALGOL 60이 사용한 "type" 대신 "class"를 사용한 것이다).
Hoare의 논문은 많은 프로그래밍 언어 기능을 논의했는데, 대부분이 새로운 것이었으며, 생성자와 소멸자를 사용한 구조화된 타입 정의, 구별된 유니온(John McCarthy에서 가져옴), 열거형, NULL 포인터 등 많은 것을 포함했다.
SIMULA 67은 Hoare가 제안한 많은 기능을 구현한 최초의 언어 중 하나였다. 제안된 기능 중 일부를 구현한 다른 언어로는 IBM PL/I, ALGOL 68, 그리고 몇 년 후인 1970년 11월의 Pascal이 있다.
키워드 "new"는 이미 Niklaus Wirth에 의해 처음 사용되었지만, Wirth에서는 Hoare에서와 다른 의미를 가졌다. 그것은 변수를 선언했다 […]
- OskarS
> 그뿐만 아니라, mfree()는 해제하는 객체의 크기를 받는데, 당연히 그래야 한다.
나는 이것이 이 업계 역사상 가장 큰 작은 실수 중 하나라고 항상 생각해왔다. 이는 대략 말해, 메모리 할당자가 그럴 필요가 없는데도 이러한 크기를 추적하도록 강제한다는 뜻이다. free()를 호출하는 사람이 할당 크기를 모르는 합리적인 경우는 거의 없으므로, 이제 우리는 그 기록을 "사용자 공간"과 메모리 할당자 내부에 두 번 유지하고 있다. 예를 들어, malloc을 호출하는 경우를 생각해보자:
* 타입 T의 단일 객체를 할당하는 경우, 크기는 그냥 `sizeof(T)`이므로 free()에 그대로 전달하면 된다.
* 객체 배열을 할당하는 경우, 크기는 `count * sizeof(T)`이며, `count`가 무엇인지 모르는 경우는 단 한 번도 생각할 수 없다. 그것은 정적으로 크기가 정해져 있거나(그 경우 그냥 상수), 동적으로 커지는 배열이라면 재할당 시점을 알기 위해 예약된 공간을 추적해야 한다. 적어도 경계 검사를 위해서라도 필요하다.
* 원시 메모리 청크의 경우에도, 이전 요점과 같은 이유로 해제할 때 할당한 원시 메모리의 크기를 아마 알 것이다. 크기 정보 없이 원시 char* 포인터만 달랑 두는 것은 끔찍한 C 관행이다.
할당 크기를 정말로 모른다면(이런 일이 언제 일어날지 상상하기 매우 어렵지만), 사용자 측에서 어떻게든 추적하도록 강제해야지, 위임해서는 안 된다 […]
- veltas
나는 여기서 작성자와 별로 공감하지 않는다. 왜냐하면 나는 '아레나 할당자'에 열광하지 않고 free가 크기를 받지 않는 것도 별로 신경 쓰지 않는다. 인터페이스는 괜찮았다고 생각한다.
또한 '아레나 할당자'는(20년 전에는 다른 의미였으므로 이름만 리브랜딩된 것 같다) 그렇게 좋지 않다. 어떤 것들은 더 쉽게 만들고 때로는 성능을 향상시키지만, 주의해서 사용하지 않으면 더 많은 메모리를 사용하고 단편화를 일으킬 수 있다. 이것이 우리가 오래된 선형 할당자에서 서서히 벗어난 여러 이유 중 하나이며, 또한 복잡성을 숨기기 위해 단순하고 유연한 인터페이스를 원했기 때문이기도 하다.
- fjfaase
리눅스의 sbrk 시스템 콜은 여전히 운영 체제로부터 더 많은 힙을 얻기 위해 사용 가능하다. 따라서 메모리는 여전히 선형 방식으로 할당되고 다시 해제되지 않는다. 아마도 이제 mmap 같은 함수들이 이것을 바꿀지도 모른다. 나는 매우 제한된 표준 라이브러리 구현을 위해 malloc을 구현하는 데 sbrk를 사용했다.
- jdw64
내가 대학생이었을 때(15년 전), A Book on C를 통해 처음 C를 접했는데, C는 단순해 보이지만 정말 많은 것을 할 수 있는 언어인 것 같다. 이 언어가 얼마나 오래되었는지, 그리고 현대 언어에서 이미 사용되는 많은 개념들이 그 개발 역사에서 시도되었는지를 보면 놀랍다. 내가 오늘날의 현대적인 기술이라고 생각했던 개념들이 이미 수십 년 전에—즉, 내가 태어나기도 전에—시도되었다는 것이 놀랍다.
Bump Allocator 같은 방법이 이미 시도되었다는 것이 놀랍다.
선배 프로그래머들은 어떻게 이 모든 것을 할 수 있었을까? 그저 놀랍기만 하다.