Fixed memory manager in C I decided to not use heap in my program and create a custom memory manager to retrieve memory chunks from a big global array of uint8_t(u8). I chose u8 since 8 bits is a byte. The very big MEMORY_BLOCK_SIZE is not a problem since in Release builds the compiler will remove the unused bytes. I keep track of free memory chunks with something i call &quot;lookups&quot;.
#include &lt;assert.h&gt;

// NOTE: null is a redefinition of NULL
// NOTE: u8 = uint8_t
// NOTE: u64 = uint64_t

#define MEMORY_BLOCK_SIZE 8388608
#define MEMORY_LOOKUPS 8

static u8 memoryBlock[ MEMORY_BLOCK_SIZE ];
static u8* memoryLookups[ MEMORY_LOOKUPS ];
static u64 memoryLookupsSizes[ MEMORY_LOOKUPS ];

void memoryInit( void )
{
     memoryLookups[ 0 ] = memoryBlock;
     memoryLookupsSizes[ 0 ] = MEMORY_BLOCK_SIZE;
}

u8* requestMemoryChunk( u64 size )
{
     assert( size );

     u8* usablePtr = null;
     u64 ptrPosition;

     for( u64 i = MEMORY_LOOKUPS; i &gt;= 0; --i )
     {
          if( ( !( memoryLookups[ i ] ) ) &amp;&amp;
                ( memoryLookupsSizes[ i ] &gt;= size ) )
          {
                usablePtr = memoryLookups[ i ];
                ptrPosition = i;
                break;
          }
     }

     assert( usablePtr );

     u8* block = usablePtr;
     
     memoryLookupsSizes[ ptrPosition ] -= size;

     if( !( memoryLookupsSizes[ ptrPosition ] ) )
          memoryLookups[ ptrPosition ] = null;
     else 
          memoryLookups[ ptrPosition ] = usablePtr + size;

     return block;
}

void freeMemoryChunk( u64 size, u8* block )
{
     assert( block &amp;&amp; size );

     for( u64 i = 0; i &lt; MEMORY_LOOKUPS; ++i )
     {
          if( ! ( memoryLookups[ i ] ) )
          {
                memoryLookups[ i ] = block;
                memoryLookupsSizes[ i ] = size;
                
                break;
          }
     }
}
```
Please, please, don't rename NULL, uint8_t and uint64_t. It makes your code super hard to read. If you really don't want to type all that out then do a find replace after you're done coding.
Well aware that checking if(!x) is the same as if(x == NULL) and if(x == 0). But ultimately, I have to favor the explicit versions for readability.
Also
for(int x=0; x&lt; MEMORY_LOOKUPS; x++) {
    uint8_t* x = requestMemoryChunk(MEMORY_BLOCK_SIZE - 1 - x);
    freeMemoryChunk(x, MEMORY_BLOCK_SIZE - 1 - x);
}
uint8_t* y = requestMemoryChunk(2);
// you just lost 99.99% of your memory

If this example is too extreme, consider
for(int x=0; x&lt; MEMORY_LOOKUPS; x++) {
    uint8_t* x = requestMemoryChunk(10000 - x);
    freeMemoryChunk(x, 10000 - x);
}
uint8_t* y = requestMemoryChunk(2);
// you just lost ~10000 bytes of memory

Consider snapping the requests to block sizes (eg powers of 2) to avoid these kinds of pathological requests. Further consider keeping the lookups sorted by size.
Stylistically things are ok. There are some unnecessary parentheses in the if conditions but (... y'know lisp exists)
Ultimately, people code in c for efficiency and control. One expects to lose some readability doing clever things. But there's no reason to not explain the clever stuff in comments.