The ring_buffer struct contains std::atomic which is a c++ object and
has a constructor, which is not called if the struct is malloc'ed.
This probably wasn't really an issue, since the constructor for those
doesn't do anything interesting anyway.
Previously it was possible to only use size - 1B, because filling the
whole buffer would make start and end indices equal, making the buffer
appear empty. This is important if we want to allow direct zero-copy
access to the buffer while storing multi-byte elements.