3

I used cv::imencode to encode a cv::Mat as image/jpeg into a vector<uchar> now I want to convert that vector to type char *.

vector<uchar> buf;

// print buf to stdout to ensure that data is valid here
for (auto c : buf)
    cout << c << endl;

// cast vector to char
char *ch = reinterpret_cast<char*>(buf.data());

// print out value of char pointer
for(int i = 0; ch[i] != '\0'; i++)
    printf("log: %c\n", ch[i]);

The for loop over the vector is taken from this question. The cast from std::vector<T> to char * is taken from this question.

The problem is now that there seems to be some data loss during the type conversion. Whereas buf contains valid data I always only get the value ???? printed from ch.

Any ideas what happened here?

Community
  • 1
  • 1
bodokaiser
  • 15,122
  • 22
  • 97
  • 140
  • 1
    Sure there are only printable characters in the buffer? – πάντα ῥεῖ May 03 '15 at 08:00
  • Why cast to `char*` not `unsigned char*`? What type of data is in `buf`? What are you actually trying to do or is this just an interest question? – ilent2 May 03 '15 at 08:01
  • This is part of a [cgo](https://golang.org/cmd/cgo/) module which does some image processing with [opencv](http://http://opencv.org). So `buf` contains this processed image as jpeg. However I think pasting the complete file would distract from the actual problem. – bodokaiser May 03 '15 at 08:07
  • @ilent2 I need to cast to `char *` as cgo cannot export `unsigned char*` to go. – bodokaiser May 03 '15 at 08:08
  • @πάνταῥεῖ yes as I get some valid characters printed in the first loop. – bodokaiser May 03 '15 at 08:10
  • 1
    What about changing the end condition of the second loop to `i < buf.size()`, just in case `buf` contains instances of `0x00`? – ilent2 May 03 '15 at 08:11
  • @bodokaiser The vector has name buf: vector buf; but in the next statement you are using name buffer char *ch = reinterpret_cast(buffer.data()); – Vlad from Moscow May 03 '15 at 08:12
  • how is `cout << c << endl;` supposed to work when it is an encoded jpeg? – M.M May 03 '15 at 08:16
  • @MattMcNabb Assuming C++11 and `uchar` is equivalent to `unsigned char` that would just output a 8 bit number for each element in `buf`. – ilent2 May 03 '15 at 08:19
  • @ilent2 you are right `buf` contains the terminating character so that `ch` will not contain the whole data. Is there any simple workaround or should I recheck cgo for other possible types? – bodokaiser May 03 '15 at 08:25

1 Answers1

3

When you work with a vector, all is fine since à vector is a dynamic array with an explicit size. So it can contain null values.

But next, you use a null terminated unsigned character array. So it stops at first null character. It is even explicit in your code.

for(int i = 0; ch[i] != '\0'; i++)
    printf("log: %c\n", ch[i]);

(the relevant part being ch[i] != 0)

That's why you loose everything after first null character.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252