16

I'm trying to store the value of an address in a non pointer int variable, when I try to convert it I get the compile error "invalid conversion from 'int*' to 'int'" this is the code I'm using:

#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

vector<int> test;

int main() {
    int *ip;
    int pointervalue = 50;
    int thatvalue = 1;

    ip = &pointervalue;
    thatvalue = ip;

    cout << ip << endl;

    test.push_back(thatvalue);

    cout << test[0] << endl;
    return 0;
}
Blachshma
  • 17,097
  • 4
  • 58
  • 72
user1934608
  • 405
  • 1
  • 4
  • 9
  • From the code you have, storing a vector of pointers and printing them would be the same thing. – chris Dec 30 '12 at 17:17
  • 1
    Why would you do that? The conversion alone is not very portable (and not every environment has `uintptr_t`), any arithmetic you may want to do with the result is either easier with pointers, or even less portable. –  Dec 30 '12 at 17:35
  • If you're converting a pointer value to an integer type, there's a very good chance that you're doing something wrong. It's a legal conversion, if you do it right (and if the machine has *some* integer type that's big enough to hold the result without loss of information), but 99% of the time you're better off just treating pointers as pointers. If you tell us what you want to do with the pointer value that you think is better done using integers, perhaps we can help you do it without the conversion. – Keith Thompson Jan 07 '13 at 16:48

6 Answers6

29

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).
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • I don't undestand, int isn't large enough to hold any pointer? but int is exactly 4294967295 in size, and thats the equivellent of FFFFFFFF in hex, and aren't pointers just holding the address of a number in memory which is somewhere between 00000000 and FFFFFFFF? Doesn't that mean that int is large enough for a pointer? That was my understanding of how this works, please correct where I am wrong. – user1934608 Dec 31 '12 at 10:19
  • @user1934608: Its not guranteed to be big enough. On some systems it will be large enough but not on all systems. For example some 64bit systems will need 64 bits for a pointer yet their integers may only be 32bit (though some will have 64bit integers it all depends). But `intptr_t` will always be large enough to hold a pointer without loss of information. Note: I use a macbook I changed your code to use a `thatvalue = reinterpret_cast(ip)` and I get the error: `error: cast from ‘int*’ to ‘int’ loses precision` – Martin York Dec 31 '12 at 21:15
  • @LokiAstari: It's important to distinguish between `int` (which is a specific type) and "integers" (which are a collection of types ranging from `char` to `long long int`). For example, a system might have a 32-bit `int` type, and a 64-bit *integer* type (called `long` or `long long`). – Keith Thompson Jan 07 '13 at 16:46
8

You can do this:

int a_variable = 0;

int* ptr = &a_variable;

size_t ptrValue = reinterpret_cast<size_t>(ptr);
sgarizvi
  • 16,623
  • 9
  • 64
  • 98
4

Why are you trying to do that, anyway you just need to cast, for C code :

thatvalue = (int)ip;

If your writing C++ code, it is better to use reinterpret_cast

benjarobin
  • 4,410
  • 27
  • 21
  • 3
    I'd suggest using C++ style casts like `reinterpret_cast` instead of old-style C casts. – Mr.C64 Dec 30 '12 at 17:18
  • 1
    reinterpret_cast is better than C style cast, the reason : http://stackoverflow.com/questions/7831696/reinterpret-cast-vs-c-style-cast – benjarobin Dec 30 '12 at 17:21
  • I tried that just now, I think the output it gave was different from the pointer address. it printed: "2293616" and "0x22ff70" all I did was replaced the line `thatvalue = ip;` with `thatvalue = (int)ip;`, am I doing something wrong? Edit: nevermind, just googled a hex to base10 converter and figured out where I went wrong.. lol – user1934608 Dec 30 '12 at 17:21
  • ... this is the same number : 2293616 = 0x22ff70 – benjarobin Dec 30 '12 at 17:22
  • 2
    This is also bound to fail. int may not by large enough to store a pointer especially on 64 bit systems. – Martin York Dec 30 '12 at 19:26
4

I'd suggest using reinterpret_cast:

thatvalue = reinterpret_cast<intptr_t>(ip);
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • 3
    Correct to use reinterpret_cast. But not the int. – Martin York Dec 30 '12 at 19:35
  • I assumed that on OP's machine `int` was large enough to store a pointer, but I agree with you that in general it's better to use `intptr_t` e.g. for some 64-bit systems, so I've updated my answer. Thanks. – Mr.C64 Jan 07 '13 at 16:44
0

I was able to use the C union statement to achieve what you were looking for. It will of course be compiler dependent, but it worked for me like you would presume it should (Linux, g++).

union {
    int i;
    void *p;
} mix;

mix.p = ip;
cout << mix.i << endl;

On my particular instance my int is 32 bit and the pointer is 48 bit. When assigning the pointer, the integer value i will represent the lowest 32 bit of the pointer.

0

Since int *ip; is a pointer to an integer and int thatvalue = 1; is an integer, assuming you want the value stored at the address pointed to by ip assigned to thatvalue, change thatvalue = ip; to thatvalue = *ip; (note the addition of the dereference operator * to access a value equivalent to the value at the pointer address).

Tom Howard
  • 4,672
  • 2
  • 43
  • 48