Earlier quoted context omitted.
> If you don't mind wasting a bit of time, you could forward size+alignment to the allocator, return the aligned version and keep a record of aligned-to-allocation mapping. (For freeing later) I'm unsure what you're proposing here - the only methods you know in the replacement allocator are operator new(size_t) and operator delete(void ). The two possible failure paths are: a = ::operator new(some size) ... ::operato…
> and then just repeatedly allocate in the hope that you will eventually get a correctly aligned value out If you preload something that patches all the new/delete interfaces, you can do this without guesswork. new(size, alignment) -> res=alloc(size+alignment) res_aligned=res+... offsets[res_aligned] = res new(size) -> alloc(size) free(ptr) -> free(offsets[ptr] || ptr) offsets.del(ptr)
You are absolutely correct that as a developer you can have your process override the allocator functions, and that is in fact what TF has done. The problem is that they have not overridden all of the allocation functions, and so they're crashing due to mismatching allocators being used. TF2 can "easily" fix this crash by implementing the aligned new, new[], delete, and delete[] operators in their custom allocator, or by simply removing their custom allocator's override of the global new & delete operators and using a common base class to get their faster allocator.
The question we're talking about is "how does the standard library respond to this scenario in a way that maximizes correctness?".