简体   繁体   中英

Using reinterpret_cast to return long long from char*

I have the following code:

char* p = "12345";

long long x = *reinterpret_cast<long long*>(p);

and I keep getting 228509037105 for x - I was expecting 12345.

What am I doing wrong?

UPDATE:

I asked the question wrongly due to my initial understanding. However, from what I have been later told it is possible to read 8 bytes from a char array using reinterpret_cast ! After all, whether bits constitute towards a value or a pointer, they are the same thing at bit-level!

A reinterpret_cast of pointers forces the compiler to reinterpret the memory address in a different data type. To convert the string "12345" to a long long 12345 you need to convert the number:

#include <sstream>

long long str2ll(const char* p) {
    std::sstream ss;
    ss << p;
    long long r;
    ss >> r;
    return r;
}

As chris on the comments says, in C++11 you can use std::stoll :

const char* p = "12345";
long long n = std::stoll(std::string(p));

Update : You can read a long long from 8 bytes of memory, but the string "12345678" reinterpreted as a long long pointer won't be the integer "12345678" but dependent on the endianess of your architecture :

const char* p = "12345678";
long long n = *reinterpret_cast<const long long*>(p);
std::cout << n << std::endl;

This program prints 4050765991979987505 or 3544952156018063160 , whether you are on a little or big endian architecture. And that's because:

hex(4050765991979987505) = 0x38 37 36 35 34 33 32 31
hex(3544952156018063160) = 0x31 32 33 34 35 36 37 38

0x38 is the hex representation of the ASCII digit 8 .

You are misunderstanding the usage of reinterpret_cast. Please read this documentation page for reinterpret_cast .

What your function does is as follows: The line char* p = "12345"; creates a pointer-to-char variable named p , which points to a memory region containing a constant buffer initialized with the 6 bytes \\0x31\\0x32\\0x33\\0x34\\0x35\\0x00 . When you would pass this variable p to, for example, printf, it would interpret the memory pointed to by p as a null-terminated string, and print "12345".

The line long long x = *reinterpret_cast<long long*>(p); creates a temporary pointer-to-long-long initialized with the value of p, meaning it points to the same memory region as p (this is actually undefined behaviour as per case 6 in the link above), then dereferences it and assigns the value to x . Because long long is usually 8 bytes long, and p only points to 6 valid bytes, this dereference is again undefined behaviour, but you are getting 228509037105 (binary 0x3534333231), which means your machine is little-endian and the extra 2 bytes are also 0.

If you want to get x == 12345 , the correct way to do it is long long x = std::stoll(p) .

You are also misunderstanding the fact that "However, from what I have been later told it is possible to read 8 bytes from a char array using reinterpret_cast". What you can do, is convert a char* value to a long long value, assuming sizeof void* is not larger than sizeof(long long) on your machine (see case 2 in the link above). If sizeof void* equals 8, then you are "reading 8 bytes from a 'char array'(actually from a pointer-to-char) : long long x = reinterpret_cast<long long>(p) . This gives you the address which p originally contained, stored as a long long value in the variable x. Anything you do with this value, except casting it back to char* , is undefined behaviour. You can do, for example, printf(reinterpret_cast<char*>(x)) , which will print your original char buffer "12345".

The underlying bytes are 0x31, 0x32, 0x33, 0x34 and 0x35 for the ascii values of 1,2,3,4 and 5 . Take the value you received and convert it to hex and you'll see what i'm talking about.

reinterpret_cast is generally used to convert between pointer types or to another integral type. For example, you could convert a pointer to a number and then use sprintf to output the value using one of the integer format specifiers instead of the pointer specifier

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM