1

I'm trying to cast some objects (the size is known) pointed by void* to a char array bitwisely in c++. I'm considering using union with a char array so that I don't need to worry too much about the casting. However, since the type of the object is unknown, I don't know how to define this union.

Just wondering if there is any other better way to deal with this?

PS: edited to avoid confusion. For instance, an integer could be cast to a 4-character array.

Thanks!

dbt
  • 103
  • 8
  • 1
    A string of bits? A `char` is the smallest addressable unit in c++. You'd have to do a conversion to string to get a string of bits. – Weak to Enuma Elish Feb 19 '16 at 21:50
  • 1
    Can you explain what you mean by "string of bits"? – Brian Bi Feb 19 '16 at 21:50
  • This might be of interest to you about type punning with unions: http://stackoverflow.com/questions/15952204/using-char-array-inside-union – Weak to Enuma Elish Feb 19 '16 at 21:54
  • Oh sorry about the confusion, I should say a string of bytes (represented by different ASCII characters). Say each integer could be represented by 4 chars. – dbt Feb 19 '16 at 21:56
  • @JamesRoot Yeah but the problem is that now the object is pointed by void*. I don't even know what the actual object type would be :( – dbt Feb 19 '16 at 21:59
  • just cast the `void*` to `char*` – user3528438 Feb 19 '16 at 22:02
  • If you ++ the pointer, what do you want the result to be? The next char or the next "string?" Do you have a fixed or max length for your string of bits? – BryanT Feb 19 '16 at 22:03
  • @user3528438 Wow this looks wonderful! Will try later and TGIF! – dbt Feb 19 '16 at 22:07
  • @BryanT After ++ the pointer, I believe that the it will go to the next unknown object. I know the size of this object though. – dbt Feb 19 '16 at 22:10

4 Answers4

3

In the link I put in the comments, the accepted answer goes into great detail about type punning and why you can't do it in c++.

What you can do is safely inspect any object with a char* (signed or unsigned) by using reinterpret_cast.

char* ptr = reinterpret_cast<char*>(&object);
for (std::size_t x = 0; x < sizeof(object); ++x)
    std::cout << ptr[x]; //Or something less slow but this is an example

If you want to actually move the object into a char[], you should use std::memcpy.

Weak to Enuma Elish
  • 4,622
  • 3
  • 24
  • 36
  • @PaulEvans I've always understood that `reinterpret_cast` to `char*` is well defined specifically to see the `char` representation of an object. This use of `reinterpret_cast` is actually `static_cast(static_cast(&object))` as far as I can tell, if that makes a difference. – Weak to Enuma Elish Feb 19 '16 at 22:24
  • Sorry, found it, you're right: "An object pointer can be explicitly converted to an object pointer of a different type.[...] if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void" – Paul Evans Feb 19 '16 at 22:30
  • @PaulEvans, since you can always access an object through a `char*`, I doubt 'all bets are off' here. – SergeyA Feb 19 '16 at 22:33
1

If you are not worried about a bit of extra memory, you can use memcpy.

int i = 10;
char carray[sizeof(i)];
memcpy(carray, &i, sizeof(i));

However, remember that carray won't be a null terminated string. It will be just an array of chars. It will be better to use unsigned char since the value in one of those bytes might be too large for char if char is a signed type on your platform.

int i = 10;
unsigned char carray[sizeof(i)];
memcpy(carray, &i, sizeof(i));
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Strange notion about being bigger. bit representation is not going to be different, and unless those are printed, there will be no difference between using char and unsigned char. – SergeyA Feb 19 '16 at 22:35
0

Why do you feel you need to worry about the casting?

Just reinterpret_cast the void pointer to a char* and iterate over each character up to the size of the original object. Keep in mind that the char* pointer is not a null-terminated string and may or may not contain null characters in the middle of the data, so do not process it like a C string.

Jordan Melo
  • 1,193
  • 7
  • 26
0

From 5.2.10 Reinterpret cast:

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void.

So you simply want to use:

char* my_bytes = reinterpret_cast<char*>(my_pointer); 
size_t num_bytes = sizeof(my_pointer);
for(size_t i = 0; i < num_bytes; ++i) {
   // *(my_bytes + i) has the most significant to least significant bytes
}
Paul Evans
  • 27,315
  • 3
  • 37
  • 54