Store address in int

May 2, 2016 at 6:04pm
Hello

Just searched around and haven't found any tips... Is it possible anyhow to store memory address (obtained from pointer) as "regular" int? And then convert it back to pointer? I need to store some pointers in an array of regular ints (as addresses are always positive I'm going to multiply them by -1 to distinguish them from other elements which should be always positive). Could you give a hint how to do this?

Thanks for help
May 2, 2016 at 6:25pm
Use intptr_t (signed) or uintptr_t (unsigned). Pointers stored in a intptr_t may not always be positive; there's no way to know if a non-zero value stored in an intptr_t is a valid pointer or not.
May 2, 2016 at 7:03pm
> I need to store some pointers in an array of regular ints
> as addresses are always positive I'm going to multiply them by -1 to distinguish them ...

(Stongly) consider using a union-like class
See 'Union-like classes' in: http://en.cppreference.com/w/cpp/language/union

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <stdexcept>

template < typename T > struct int_or_ptr
{
    enum item_type { INT, PTR };

    struct type_error : virtual std::domain_error { type_error() : std::domain_error( "type error" ) {} };

    int_or_ptr( int i = 0 ) : tag(INT), int_val(i) {}
    int_or_ptr( T* p ) : tag(PTR), ptr_val(p) {}

    item_type type() const { return tag ; }

    operator int& () { if( tag != INT ) throw type_error() ; return int_val ; }
    operator const int& () const { if( tag != INT ) throw type_error() ; return int_val ; }

    operator T*& () { if( tag != PTR ) throw type_error() ; return ptr_val ; }
    operator T* const& () const { if( tag != PTR ) throw type_error() ; return ptr_val ; }

    private:

        item_type tag ;

        union
        {
            int int_val ;
            T* ptr_val ;
        };


    friend std::ostream& operator<< ( std::ostream& stm, int_or_ptr ip )
    { return ip.tag == INT ? stm << ip.int_val : stm << ip.ptr_val ; }
};

int main()
{
    int a[] = { 1, 23, 456, 7890 } ;

    int_or_ptr<int> mixed[] = { a[0], a+0, a[1], a+1, a[2], a+2, a[3], a+3 } ;
    for( auto& ip : mixed ) std::cout << ip << ' ' ;
    std::cout << '\n' ;

    int value = mixed[4] ;
    int* pointer = mixed[5] ;
    mixed[4] = mixed[5] ;
    // etc
}
May 2, 2016 at 7:11pm
It's possible but it's a bad idea. Why is it necessary? Is it actually necessary?
Topic archived. No new replies allowed.