Reputation: 2545
Need to safe convert array from unsigned char* to char*. I do it this way. Is it correct or not?
std::vector < unsigned char > arr;
char *imgData = (char*) malloc( arr.size() );
for ( int i = 0; i < arr.size(); i++ ) imgData[ i ] = ( arr.at( i ) - 128 );
Upvotes: 3
Views: 1093
Reputation: 473427
No, that is not safe. Or more to the point, it's not well-defined behavior in C++.
char
is allowed to be signed or unsigned, however the implementation sees fit. If char
is unsigned, subtracting 128 from the unsigned char
will just truncate half of the bits. And if char
is signed, there's no guarantee that it's two's complement signed, so subtracting 128 won't do what you want.
The kind of conversion you're trying to do is not reasonable. You named the variable imgData
, so it seems like you intend to send that data to some image API. And that API takes regular char
. So your goal seems to be to convert each unsigned char
into a char
that shares the exact same bit-pattern of the original unsigned char
.
In that case... just cast the pointer: static_cast<char*>(arr.data())
. You're going to provoke undefined behavior either way; I'd rather do it in the way that's likely to actually work ;)
Also, it should be noted that C++14 makes it effectively impossible to implement a signed version of char
that doesn't use two's complement. That's because of the need to support UTF-8 through a possibly-signed-char
type. You have to be able to cast a char*
into an unsigned char*
and back, in such a way that the bit-pattern of all valid UTF-8 code units is preserved.
So the cast still is the option most likely to actually do what you want.
Upvotes: 5