Memory management in early Unix
A programmer's examination of recovered Unix source code has highlighted how the operating system's earliest C programs managed memory with interfaces that differ sharply from the malloc and free functions familiar to modern developers. The analysis follows allocator code from the fourth edition of Unix, released in 1973, through later editions as the language and system evolved.
In fourth-edition compiler sources, the author found a simple linear allocator that aligned each request, checked the remaining region and extended the process heap with sbrk when necessary. The program did not free individual allocations. Memory remained available for its lifetime, an economical design when a short-lived tool could discard everything on exit. Failure terminated the process, so callers did not repeatedly check for a null result.
More strikingly, a file in Dennis Ritchie's source directory contained functions named malloc and mfree whose signatures did not match their modern descendants. Both accepted an explicit map argument, while mfree also received the size of the region being released. Kernel code passed structures named coremap and swapmap, representing separate pools of main memory and swap space.
That approach let one allocation routine operate on different resources without embedding knowledge of what each pool represented. The maps maintained address-ordered lists of available blocks, using a first-fit policy and combining adjacent free regions. The interface resembles arena-based allocation in allowing memory to be partitioned by purpose, though the analysis cautions against assuming its designers were pursuing today's software-isolation goals; hardware and operating-system resource constraints offered a direct reason for the design.
Ideas changed as Unix and C matured
The source tour found related linear-allocation techniques in sixth-edition utilities. An early version of diff could advance a shared area pointer for allocations and later roll it back, an efficient pattern when groups of temporary objects share a lifetime. By the seventh edition, individual programs had introduced macros that combined allocation with type-size calculations, foreshadowing conveniences used in later C and C++ code.
These examples do not establish a single straight line from early Unix routines to the standardized C library. The kernel resource allocator and user-space heap allocator solved different problems, and names and interfaces shifted across editions. They do show that explicit regions, bulk lifetime management and size-aware deallocation are not recent inventions. Developers continue to use variants of those concepts in arenas, pools and application-specific allocators.
The renewed examination was made possible by preservation of historical source material, including a fourth-edition Unix tape found decades after the system's release. Reading the code provides more than nostalgia: it exposes design choices made under severe hardware limits and shows how simple, purpose-built allocation could replace a universal heap interface.
For modern programmers, the lesson is not that one early design should replace standard malloc. It is that allocation interfaces encode assumptions about ownership, lifetime and failure. Early Unix made those assumptions explicit in ways that remain relevant when software needs predictable resource limits or fast disposal of related objects.



