You can easily make free a no-op:
fn my_free (_: *anyopaque, _: []u8, alignment: Alignment, _: usize) void {}
const my_vtable = blk:{
// If we could just grab the functions
// inside the Arena implementation,
// we could easily create a new vtable
// with free replaced. But these functions
// are private, so we do a little dance to
// grab them.
var arena: std.heap.ArenaAllocator = undefined;
const allocator = arena.allocator();
var vtable = allocator.vtable;
vtable.free = my_free;
break :blk vtable;
};
fn myArenaAllocator(arena: *std.heap.ArenaAllocator) Allocator{
var allocator = arena.allocator();
allocator.vtable = &my_vtable;
return allocator;
}