For I/O work, I need to read N bytes into a buffer. N is known at run time (not compile time). The buffer size will never change. The buffer is passed to other routines to compress, encrypt, etc: it's just a sequence of bytes, nothing higher than that.
In C, I would allocate the buffer with malloc
and then free
it when I'm done. However, my code is modern C++, certainly no malloc
s in place, and very few raw new
and delete
: I'm making heavy use of RAII and shared_ptr
. None of those techniques seem appropriate for this buffer, however. It's just a fixed length buffer of bytes, to receive I/O and make its contents available.
Is there a modern C++ idiom to this elegantly? Or, for this aspect, should I just stick with good ol' malloc
?
In C++14, there's a very syntactically clean way of achieving what you want:
size_t n = /* size of buffer */;
auto buf_ptr = std::make_unique<uint8_t[]>(n);
auto nr = ::read(STDIN_FILENO, buf_ptr.get(), n);
auto nw = ::write(STDOUT_FILENO, buf_ptr.get(), nr);
// etc.
// buffer is freed automatically when buf_ptr goes out of scope
Note that the above construct will value-initialize (zero out) the buffer. If you want to skip the initialization to save a few cycles, you'll have to use the slightly uglier form given by lisyarus:
std::unique_ptr<uint8_t[]> buf_ptr(new uint8_t[n]);
C++20 introduces std::make_unique_for_overwrite
, which allows the non-initializing line above to be written more concisely as:
auto buf_ptr = std::make_unique_for_overwrite<uint8_t[]>(n);