readFileAlloc does not over-allocate. the length of the returned slice is the length of the file.
there cannot be a file longer than std.math.maxInt(usize) - the OS itself can't handle that!
as for const and var values not needing to be freed... this is a big topic, but I'll give you a rundown: the data in your program is stored in one of three places: the stack, the heap, or static memory (for pedants: not gonna get into multithreading here...).
static memory holds global variables and constants (your string literals go there!), values living in static memory have, well, static lifetime - they are accessible throughout your program.
a value defined locally in a function, with const or var lives on the stack (except for consts that are evaluated at compile-time, those go in static memory) - these values have lifetime beginning at their declaration and until the end of the scope they're in (the closing }); the memory they take up is automatically discarded and is available for reuse at scope's end.
the problem with the first two places is that the size of the values they hold needs to be known at compile-time (for pedants: not gonna talk about alloca!), so we can't for example store a file's contents in there - we don't know its length! and so we use the 3rd place, the heap.
the heap is a storage place, growable by asking nicely from the OS, in which values can be stored for a dynamic time period. std.heap.page_allocator is a thin wrapper around this ask-the-OS-for-more-heap, and std.heap.GeneralPurposeAllocator (with default settings...) is a wrapper around that. whenever you allocate some memory from the allocator it searches for a place in the heap to, well, allocate to you (asking the OS for more heap if no space was found). it returns you a pointer to that memory.
after you're done with the memory you must tell the allocator about this, so that it'll be able to reuse the memory for some other allocation.