Converting a Pointer into an Integer

Converting a pointer into an integer

Use intptr_t and uintptr_t.

To ensure it is defined in a portable way, you can use code like this:

#if defined(__BORLANDC__)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
typedef unsigned long uintptr_t;
#elif defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
#else
#include <stdint.h>
#endif

Just place that in some .h file and include wherever you need it.

Alternatively, you can download Microsoft’s version of the stdint.h file from here or use a portable one from here.

Conversion of integer pointer to integer

Apparently you confuse the pointer with the content of the pointer.

As an analogy to the real world, you could say that, with me pointing at a bird, you want to convert my index finger to a bird. But there is no relation between the type 'bird' and 'finger'.

Transferring that analogy to your program: you are converting the object pointing to your int to an int itself. Since a C pointer is implemented as 'the number of a memory cell', and since there are lots of memory cells available, it's obvious that (int)p will result in a very big number.

Casting is a nasty thing. It's a coincidence that pointers are quite analogous to integers. If they were implemented as "the nth address of the mth memory bank", you wouldn't be asking this question because there wouldn't have been an obvious relation, and you wouldn't have been able to do this cast.

how to convert pointer to integer in c?

The best way to use an integer type to hold a pointer value is to use uintptr_t type.

From the C11, chapter 7.20.1.4,

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

 uintptr_t

If you want a signed integer type instead, use intptr_t.

Pointer to integer conversion in C

As the text you cite states, the result is implementation-defined. Per C 3.4.1, this is:

unspecified behavior where each implementation documents how the choice is made.

Thus, the C implementation you are using (primarily the compiler) is required to document how the result is determined.

In implementations with “flat” virtual address spaces, where each pattern of bits within a certain range represents an address, it is common to simply reinterpret the bits as a binary numeral. So the address 1 0000 0000 would be converted to the number 256.

However, implementations with some form of base-and-offset or segment-and-offset addressing might form an integer with the base in some bits and the offset in another, and there are other possibilities.

Casting pointer to an integer

The standard C11 (as an example that I have at hand) says in chapter 6.3.2.3 "Pointers" in paragraph 5:

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

The mentioned exception is about the value 0, which yields a null pointer.

Paragraph 6 is on the other way:

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

Any time I see "implementation-defined" or "undefined behavior", the code will be generally not portable. If you prefer to write good code, refrain from using such constructs. However, if you know what you are doing, and if you test your expectations, you might get away with it.

BTW, the difference of two pointers not pointing into the same array (or exactly past the end of it) is undefined behavior, too.


EDIT:

Chapter 7.20.1.4 "Integer types capable of holding object pointers" of the same standard says:

The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

intptr_t

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

uintptr_t

These types are optional.

The last sentence is important.

How to fix casting a pointer to an integer?

How to fix casting a pointer to an integer?

Don't assign an int to a pointer and then the need for casting is gone.

Assign a pointer to a pointer.

// temp->next = (struct Node*) newNode->data;
temp->next = newNode;

How do I cast a pointer to an int

int may not be large enough to store a pointer.

You should be using intptr_t. This is an integer type that is explicitly large enough to hold any pointer.

    intptr_t thatvalue = 1;

// stuff

thatvalue = reinterpret_cast<intptr_t>(ip);
// Convert it as a bit pattern.
// It is valid and converting it back to a pointer is also OK
// But if you modify it all bets are off (you need to be very careful).

Convert pointer to int and back to typed object

The best thing to do is to fix your project so it can deal with pointers. Integers and pointers are two different things. You can convert back and forth, but such conversions can lose information if you're not careful.

Converting a pointer value to int and back again can easily lose information, depending on the implementation and the underlying platform. For example, there are systems on int is smaller than a pointer. If you have 32-bit ints and 64-bit pointers, then converting a pointer to an int and back again will almost certainly give you an invalid pointer.

It's very likely that long or unsigned long is wide enough to hold a converted pointer value without loss of information; I've never worked on a system where it isn't. (Personally, I tend to prefer unsigned types, but not for any really good reason; either should work equally well.)

So you could write, for example:

SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<unsigned long>player;

and convert the unsigned long value back to a pointer using reinterpret_cast,SoundPlayer*>.

Newer implementations provide typedefs uintptr_t and intptr_t, which are unsigned and signed integer types guaranteed to work correctly for round-trip pointer-to-integer-to-pointer conversions. They were introduced in C99, and optionally defined in the <stdint.h> header. (Implementations on which pointers are bigger than any integer type won't define them, but such implementations are rare.) C++ adopted them with the 2011 standard, defining them in the <cstdint> header. But Microsoft Visual C++ does support them as of the 2010 version.

This guarantee applies only to ordinary pointers, not to function pointers or member pointers.

So if you must do this, you can write:

#include <cstdint>
SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<std::uintptr_t>player;

But first, consider this. new FxPlayerTiny() gives you a pointer value, and you're going to want a pointer value. If at all possible, just keep it as a pointer. Converting it to an integer means that you have to decide which of several techniques to use, and you have to keep track of which pointer type your integer value is supposed to represent. If you make a mistake, either using an integer type that isn't big enough or losing track of which pointer type you've stored, the compiler likely won't warn you about it.

Perhaps you have a good reason for needing to do that, but if you can just store pointers as pointers your life will be a lot easier.



Related Topics



Leave a reply



Submit