Skip to content

ArjunVasavan/memory_allocator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alloc — Custom Heap Memory Allocator

A lightweight heap allocator written in C and x86-64 NASM assembly. Manages a 1GB static heap using a linked list of block headers, supporting allocation, freeing, and heap inspection.


Architecture

The heap is a flat 1GB region defined in assembly (heap.asm) and exposed to C via the memspace symbol. Each allocation is preceded by a 4-byte header struct:

 ┌─────────────────────────────────────┐
 │ header (4 bytes)                    │
 │  w        : 30 bits  — block size   │
 │  alloced  :  1 bit   — in use flag  │
 │  reserved :  1 bit   — unused       │
 ├─────────────────────────────────────┤
 │ user data  (w * 4 bytes)            │
 └─────────────────────────────────────┘

Block sizes are stored in words (1 word = 4 bytes). The special sentinel value ZeroWords (0x3FFFFFFF) represents a zero-size block, used to mark the end of the heap.


Files

File Description
alloc.c Allocator implementation
alloc.h Types, macros, and function declarations
heap.asm 64-bit NASM assembly — defines the 1GB heap
Makefile Build system

API

void *alloc(int32 bytes)

Allocates at least bytes bytes from the heap. Rounds up to the nearest 4-byte word boundary. Returns a pointer to the usable memory, or NULL on failure with errno set.

int8 *p = alloc(64);

bool destroy(void *addr)

Frees a previously allocated block. Zeroes the memory and marks the block as free. Returns true on success. Sets errno to Err2xFree and returns NULL if the block is already free or invalid.

destroy(p);

show()

Macro that prints a map of all blocks on the heap — address, index, size in words, and allocation status.

show();

Example output:

0x00404034 Alloc 1 = 2 alloced words
0x00404040 Alloc 2 = 499 alloced words
Empty header at 0x0040480c, moving on
0x00404814 Alloc 4 = 3 alloced words

Error Codes

Set in errno on failure:

Constant Value Meaning
ErrNoErr 0 No error
ErrNoMem 1 Heap exhausted
ErrUnknown 2 Unknown error
Err2xFree 4 Double-free attempted

Convenience Macros

allock(n)   // alloc(n * 1024)        — allocate n kilobytes
allocm(n)   // alloc(n * 1024 * 1024) — allocate n megabytes
allocg(n)   // allocm(n * 1024)       — allocate n gigabytes

Building

Requires GCC and NASM.

make

Produces the alloc binary. PIE is disabled (-no-pie) because the heap uses absolute 32-bit relocations in the ASM.

make clean   # remove build artifacts

Implementation Notes

  • Block splitting — if a free block is larger than requested, mkalloc splits it and writes a new header for the remainder.
  • First-fitfindblock_ walks the list recursively and returns the first free block large enough to satisfy the request.
  • No coalescing — adjacent free blocks are not merged. Repeated alloc/free cycles on varied sizes will fragment the heap over time.
  • No thread safety — no locking; not safe for concurrent use.
  • Max allocationMaxwords caps a single allocation at (1GB/4) - 1 words.

About

Trying to create my own custom memory allocator

Resources

Stars

Watchers

Forks

Contributors