简体   繁体   中英

Casting pointers in C++?

Running this code returns what I assume to be the integer value of realPtr 's address.

I'm still new to C++ and I was wondering - is it possible to convert from one data type pointer to another and the pointer variable whose value is assigned will still print out the right value (ie *integerPtr prints out 2)?

Code snippet

double real = 2.0;
double *realPtr = ℜ
int *integerPtr;
integerPtr = ((int*)&realPtr);
cout << *integerPtr << endl;

Output

1606416424

Thanks!

There are 3 totally different types that you are dealing with here:

  • Pointers point to any location in memory. Every pointers are basically the same type, but they are treated as different types depending on what you declare them to point to.
  • int, and double are types that represent integer and real numeric value; An integer and a double representing the same numerical value (eg 2) will not have the same binary content as stipulated by the relevant standard defining how integers and floating point numerics are stored in memory.

Since every pointers are essentially the same type, you may cast a kind of pointer to any other kind. Let's say you have your own Foo class that has nothing to do with representing numerical value. You may still do this:

int* p_int = 2;
Foo* p_foo = (Foo*) p_int;

This is legal, but this will most probably lead to an error, unless the memory representation of a Foo object is akin to that of an int.

If you want to cast an int to a double, you must cast the data, casting the pointer won't do anything. That's why there are several cast with different names in C++11, and it is considered good practice to use them since by doing so you express explicitly what you want to be done. In your case, you may want one of two different things

Reinterpret_cast

Casting a pointer to an int to a pointer to a double, which means essentially doing nothing except telling the compiler that it can safely assume that the data pointed to can be considered as a double. The compiler will assume so, and it is your responsibility to assure that it is the case. This type of cast is considered the most dangerous since as we all know, programmers can't be trusted. It is called a reinterpret_cast:

int* p_int = 2;
Foo* p_foo = reinterpret_cast<int>(p_int); 

Same code as above, but we express the danger in the scary "reinterpret_cast". p_int and p_foo have the same value, we did nothing except expressing the fact that we now consider the address of our integer as an address to a foo.

Static_cast

If you want a real cast, you have to operate on the data, not on the pointer. Casting a type of data to another by whatever means the compilers know of is called static_cast. This is probably what you want to do here:

int i = 2;
p_int = &i;
double d = static_cast<double>(i);
p_double = &d; //p_int and p_double have different values since they point to different objects.

The compiler will look for a conversion function from int to double, and yell at you if it doesn't find any.

Of course, there is nothing wrong with doing the exact same thing by using only pointers, although it makes the code slightly less readable (you should be wary of using pointers at all, and do it for a good reason):

int* p_i = 2;
int* p_d = static_cast<double>(*p_i) // p_d is a pointer to a double initialized to the value obtained after converting the int pointed to by p_i

The internal representation of float/dobule and integer data types are different. In a 32 bit PC Integer will take 4 bytes while a double take 8 bytes.

Also there is a serious bug in your code.

double real = 2.0;
double *realPtr = &real;

int *integerPtr;
integerPtr = ((int*)&realPtr);

cout << *integerPtr << endl;

In the above code see the bold lines. There you declared a pointer to an integer called "integerPtr". But the actual value stored address of a pointer to a double. ie &realPtr is double ** (Pointer to a pointer which holds a double type value). And then you are trying to print the value using *integerPtr.

So I changed your code as follows and it gives a value of 0.

double real = 2.0;
double *realPtr = &real;
int *integerPtr;
integerPtr = ((int*)realPtr);

std::cout << *integerPtr << std::endl;

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