Emiliano
Emiliano

Reputation: 109

copying std::vector<unsigned char> to void * buffer using memcpy

I have a custom function which copying values to the buffer

void foo(void *buffer, std::initializer_list<unsigned char> l) {
   memcpy(buffer, l.begin(), l.size());
}

Initializer list argument takes hexadecimal value as paramater. However I want to change it to string representation like instead of passing parameter as {0x01, 0x02, 0x04}, I would like to pass it as "0x01 0x02 0x04".

I changed std::initializer_list<unsigned char> to std::vector. But I got invalid casting error from vector to void *.

void foo(void *buffer, std::vector<unsigned char> l) {
   memcpy(buffer, reinterpret_cast<void *>(l.begin()), l.size());
}

Upvotes: 1

Views: 1746

Answers (3)

Pete Becker
Pete Becker

Reputation: 76417

If using memcpy isn't an absolute requirement, there's a higher-level approach:

std::uninitialized_copy(l.begin(), l.end(), (unsigned char*)buffer);

But I'd make it more general:

template <class Iter>
void foo(void *buffer, Iter first, Iter last) {
    typedef typename std::iterator_traits<Iter>::value_type *ptr;
    std::uninitialized_copy(first, last, static_cast<ptr>(buffer));
}

This one works with any range and any type.

Upvotes: 1

WieeRd
WieeRd

Reputation: 1107

Although iterators returned from .begin() or .end() might work like pointers,
but that does not guarantee that they are really alias of real pointers.
Think of iterators from std::map for example.
They should contain more information rather than just a pointer since they iterate through binary tree.

It makes sense to think of iterator from continuous container as pointer,
maybe they really are, but remember the C++ standard does not guarantee it.

Anyways, here's my solution.

void foo(void *buffer, std::vector<unsigned char> l) {
   memcpy(buffer, &*l.begin(), l.size());
}

Looks weird but does the job correctly.
The other answer's solution looks more elegant tho :)

Upvotes: 1

G.M.
G.M.

Reputation: 12899

std::vector::begin returns an iterator not a pointer to the first element. Try...

void foo(void *buffer, std::vector<unsigned char> l)
{
    memcpy(buffer, l.data(), l.size());
}

Better still, if the vector is large then you might want to consider passing by const reference rather than by value...

void foo(void *buffer, const std::vector<unsigned char> &l)
{
    memcpy(buffer, l.data(), l.size());
}

Upvotes: 2

Related Questions