# K06 — `MemoryResource` and `FreeRtosAllocator` K06 introduces runtime-selected storage without virtual dispatch. A [`MemoryResource`](include/freertos/memory_resource.hpp) is exactly: ```text context pointer + allocate function pointer + deallocate function pointer ``` Two providers expose the same byte-level contract: - `HeapResource` delegates to `pvPortMalloc()`/`vPortFree()` and releases an individual block; - `StaticArenaResource` performs aligned monotonic allocation from a caller supplied buffer, ignores individual deallocation and recovers all storage only through `reset()`. [`FreeRtosAllocator`](include/freertos/free_rtos_allocator.hpp) converts an element count to bytes only after proving `count <= SIZE_MAX / sizeof(T)`. Its `try_allocate()` is explicitly fallible; it does not pretend to have the fail-fast ordinary-`new` contract from K05. ## Experiment The same typed operation allocates 16 `uint32_t` values (64 bytes) from each resource. The checked Hazard3 run reports: ```text heap address = 0x80002b10 (inside ucHeap) arena address = 0x80006e00 (inside g_static_arena_storage in .bss) arena used after allocate = 64 arena used after deallocate = 64 arena used after reset = 0 ``` The executable also proves two failure levels: 1. multiplication overflow is rejected by the typed allocator before either resource function is called; 2. a valid byte count that exceeds remaining capacity returns `nullptr` while heap free bytes and arena offset remain unchanged. ## Seven checkpoints | Point | Evidence | | --- | --- | | 1 | contexts and two distinct allocate function addresses captured | | 2 | identical typed buffers aligned; heap in `ucHeap`, arena in `.bss` | | 3 | overflow counts rejected before resource counters/storage change | | 4 | capacity failures leave heap availability and arena offset unchanged | | 5 | heap deallocation returns current free bytes to baseline | | 6 | arena deallocation is deliberately a no-op | | 7 | arena reset returns used bytes to zero; counters and PASS checked | ## Build ```sh make check ``` Expected summary: ```text PASS host: non-virtual resources, overflow and unchanged failures PASS ABI: context/function-pointer resources; no vtable or hosted allocator PASS task01: runtime resource + typed allocator + failures ``` ## Debug ```gdb b allocator_resource_debug_checkpoint p g_last_checkpoint p/x g_heap_context p/x g_arena_context p/x g_heap_allocate_function p/x g_arena_allocate_function p/x g_heap_address p/x g_arena_address p/x g_arena_storage_begin p/x g_arena_storage_end p g_heap_after_capacity_failure p g_arena_used_after_allocation p g_arena_used_after_deallocate p g_arena_used_after_reset p g_allocator_resource_pass ``` ## Scope boundary The arena may be reset only when no live object still refers to its storage. K06 allocates storage for trivial values and keeps lifetime management visible; it does not claim STL allocator conformance, invoke constructors, or hide resource failure. Owning containers and task policies build on these contracts in later cards.