Memcpy-ing to a const char pointer? AFAIK this does no harm as long as we know what we do, but is this good behavior and why?
The current code may have undefined behavior, depending on the C++ version. To avoid undefined behavior in C++14 and below take the address of the first element. It yields a non-const pointer:
buff.resize(size);
memcpy(&buff[0], &receiver[0], size);
I have recently seen a colleague of mine using std::string
as a buffer...
That was somewhat common in older code, especially circa C++03. There are several benefits and downsides to using a string like that. Depending on what you are doing with the code, std::vector
can be a bit anemic, and you sometimes used a string instead and accepted the extra overhead of char_traits
.
For example, std::string
is usually a faster container than std::vector
on append, and you can't return std::vector
from a function. (Or you could not do so in practice in C++98 because C++98 required the vector to be constructed in the function and copied out). Additionally, std::string
allowed you to search with a richer assortment of member functions, like find_first_of
and find_first_not_of
. That was convenient when searching though arrays of bytes.
I think what you really want/need is SGI's Rope class, but it never made it into the STL. It looks like GCC's libstdc++ may provide it.
There a lengthy discussion about this being legal in C++14 and below:
const char* dst_ptr = buff.data();
const char* src_ptr = receiver.data();
memcpy((char*) dst_ptr, src_ptr, size);
I know for certain it is not safe in GCC. I once did something like this in some self tests and it resulted in a segfault:
std::string buff("A");
...
char* ptr = (char*)buff.data();
size_t len = buff.size();
ptr[0] ^= 1; // tamper with byte
bool tampered = HMAC(key, ptr, len, mac);
GCC put the single byte 'A'
in register AL
. The high 3-bytes were garbage, so the 32-bit register was 0xXXXXXX41
. When I dereferenced at ptr[0]
, GCC dereferenced a garbage address 0xXXXXXX41
.
The two take-aways for me were, don't write half-ass self tests, and don't try to make data()
a non-const pointer.