Modern C++ idiom for allocating / deallocating an I/O buffer

Basically, you have two main C++-way choices:

  • std::vector
  • std::unique_ptr

I’d prefer the second, since you don’t need all the automatic resizing stuff in std::vector, and you don’t need a container – you need just a buffer.

std::unique_ptr has a specialization for dynamic arrays: std::unique_ptr<int[]> will call delete [] in it’s destructor, and will provide you with appropriate operator [].

If you want the code:

std::unique_ptr<char[]> buffer(new char [size]);
some_io_function(buffer.get(), size); // get() returnes raw pointer

Unfortunatelly, it doesn’t have a way to retrieve the size of the buffer, so you’ll have to store it in a variable. If it confuses you, then std::vector will do the work:

std::vector<char> buffer(size);
some_io_function(buffer.data(), buffer.size()); // data() returnes raw pointer

If you want to pass the buffer around, it depends on how exactly you do it.

Consider the following case: the buffer is filled somewhere, then processed somewhere else, stored for some time, then written somewhere and destroyed. It happens that you never really need two places in the code to own the buffer, and you can simply std::move it from place to place. For this use case, std::unique_ptr will work perfectly, and will protect you from occasionally copying the buffer (while with std::vector you can copy it by mistake, and no error or warning will arise).

If, conversely, you need several places in the code to hold the same buffer (maybe it is filled / used / processed in more then one place simultaneously), you definitely need std::shared_ptr. Unfortunately, it does not have array-like specialization, so you’ll have to pass appropriate deleter:

std::shared_ptr<char> buffer(new char[size], std::default_delete<char[]>());

The third option is if you really need to copy the buffer. Then, std::vector will be simpler. But, as I’ve already mentioned, I feel that it is not the best way. Also, you can always copy the buffer hold by std::unique_ptr or std::shared_ptr manually, which clearly documents your intention:

std::uniqure_ptr<char[]> buffer_copy(new char[size]);
std::copy(buffer.get(), buffer.get() + size, buffer_copy.get());

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)