35

I have a buffer like this:

vector<unsigned char> buf

How can I cast it to char*?

If I do:

(char *)buf

I get this error:

/home/richard/Desktop/richard/client/src/main.cc:102: error: invalid cast from type ‘std::vector<unsigned char, std::allocator<unsigned char> >’ to type ‘char*’

For those wondering why I am trying to do this. I need to pass the buffer to this function:

n_sent = sendto(sk,(char *)buf,(int)size,0,(struct sockaddr*) &server,sizeof(server));

And it only accepts char*.

Richard Knop
  • 81,041
  • 149
  • 392
  • 552

4 Answers4

69
reinterpret_cast<char*> (&buf[0]);

The vector guarantees that its elements occupy contiguous memory. So the "data" you seek is actually the address of the first element (beware of vector <bool>, this trick will fail with it). Also, why isn't your buffer vector<char> so that you don't need to reinterpret_cast?

Update for C++11

reinterpret_cast<char*>(buf.data());
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    I am using OpenCV to get the buffer and the function I am using returns vector. I then need to pass the buffer to another function which only takes char*. – Richard Knop Nov 23 '10 at 10:02
  • @Richard: fair enough, in this case reinterpret_cast is justified :) – Armen Tsirunyan Nov 23 '10 at 10:12
  • 2
    +1: Might I add that the reinterpret_cast serves only the purpose of the `unsigned char`->`char` conversion, if you wouldn't have needed that, you could leave that out. – rubenvb Nov 23 '10 at 12:11
  • @Richard: you need to know once, and can then ignore, that this conversion doesn't necessarily work on implementations that have a signed char, which isn't 2's complement. The problem there is that reinterpreting an unsigned char as a char can result in a different value from converting it to char, and you'd have to check the specific functions to know which one is appropriate. If char is unsigned, or if it's 2's complement (and the implementation uses the obvious conversion), then there's no difference. – Steve Jessop Nov 23 '10 at 13:05
  • I found this post to get my code working, however as soon as I try to read from my buffer after reading into it from my file, I get a "Invalid read of size 1" / "Address 0x1000e00 is not stack'd, malloc'd or (recently) free'd" from Valgrind. I would think if I did something wrong. My ifstream.read() would have failed for memory not being available. – JoeManiaci Jan 11 '16 at 19:40
  • Quite old subj, but for others benefit - when converting vector to char* with data() do not forget that it could have no 0 character in the end, so you can easily have garbage after your data. So one might want to convert it like: char* cstr=buf.data(); cstr[buf.size()] = 0; – Vladimir T Nov 05 '20 at 19:27
9
reinterpret_cast<char*>(buf.data());
ronag
  • 49,529
  • 25
  • 126
  • 221
4

Try

(char *)(&buf[0])

or another, more C++ cast. But also tell us what you're using this for. It may be a bad idea.

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
4

It's very unlikely that you want to cast vector<unsigned char> to unsigned char *, but you can get a a valid pointer like this:

vector<unsigned char> v;
unsigned char *p = &*v.begin();

That strange expression will give you the pointer to the start of the internal allocated array created by the vector. If you modify the vector at all it may no longer be valid.

The reason for the redundant looking &* is that the * is really operator * on the iterator returned by v.begin(). That returns a reference to the first char of the array which you can then take the address of with &.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
  • 3
    alternatively, `v.front()`, `v.at(0)` and `v[0]` will give a reference to the first element, so dereferencing `v.begin()` doesn't bring anything here. – Matthieu M. Nov 23 '10 at 10:11
  • Quite true. I had a rather one-track mind as I wrote it, and others provided more succinct answers while I was typing, so I just left it in case something of the nature of getting the internals of a vector was useful. – Ben Jackson Nov 23 '10 at 10:17
  • Completely not unlikely at all. I'm working, wight now, with two apis ... one that std/move returns a char vector, and the other uses an unsigned char pointer... and i know that both should be treated as arbitrary bytes without conversion. – Erik Aronesty Dec 03 '18 at 23:06