Saturday, September 3, 2016

Replacing legacy C-style buffers

Since I've been working lately on legacy projects, filled with C-style buffer containers like void*, char*, byte*, I've started replacing these types of buffers with something a bit more safe and modern, if I might say so.

The new buffer containers I've used are std::vector. The replacement would look like this:
  • let's take a classic C-style buffer
void* pBuffer = ...;
size_t size = ...;
  • assigning the contents to a std::vector would look like this:
std::vector<unsigned char> vBuffer;
vBuffer.insert(vBuffer.end(), (unsigned char*)pBuffer, (unsigned char*)pBuffer+size);
  • now the same buffer data can be used by accessing the std::vector internal raw container:
vBuffer.data()
So you can start "drop-in" replacing pBuffer with vBuffer.data().
The benefits would be:

  • you have RAII style memory management, no more manual memory freeing
  • code looks cleaner, easier to read and maintain
  • you can use STL algorithms to manipulate the data

Of course, it's not a 1-size-fits-all solution. There may be times when you have to use the raw, dynamic allocated buffers and pass them around, depending on the context.
I've seen people use std::string for the same purpose of holding binary data. It is possible, but it may be misleading to maintainers, since strings are supposed to be strings and contain string data.

No comments:

Post a Comment