Load value of a memory address stored as an unsigned 32-bit int

Sorry if the title doesn't make sense

I am trying to use the memory address of an object to create a unique ID for it. I want to be able to use that unique ID(which is the memory address, I think) to reference the object and use it.

UniqueID.h
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
 #pragma once
#include <cstdint>
#include <vector>
#include <utility>
#include <string>


class UniqueID
{
public:
	template <class UnknownObject>
	static uint32_t generateID(UnknownObject unknown);

	template <class UnknownObject>
	static uint32_t getID(UnknownObject);
//protected:
	static std::vector< std::pair<uint32_t, std::string > > m_IDs;
};

template<class UnknownObject>
inline uint32_t UniqueID::generateID(UnknownObject unknown)
{
	uint32_t id = reinterpret_cast<uint32_t>(&unknown);
	std::string name = typeid(unknown).name();
	m_IDs.push_back(std::pair<uint32_t, std::string>(id, name));
	return id;
}

template<class UnknownObject>
inline uint32_t UniqueID::getID(UnknownObject)
{
	
}


main.c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include "UniqueID.h"
#include <iostream>

int main()
{
	UniqueID::generateID<unsigned long long int>(a);

	std::cout << UniqueID::m_IDs[0].first << std::endl;
	std::cout << UniqueID::m_IDs[0].second << std::endl;

	
        system("PaUSE");
	return 0;
}


UniqueID.cpp is just a declaration

As you can see I used uint32_t id = reinterpret_cast<uint32_t>(&unknown); to convert the object to a memory address.

how do I turn this number(stored in UniqueID::m_IDs[0].first) into a usable reference?
I don't see the problem?

Just cast first back to a pointer. Of course you need to ensure that the object still exists. And it works only for pointer that do not exceed 32 bit.
How can I cast it back to a pointer, I've tried but I don't get the right value.

Also I'm sure these is a more efficient way of creating an ID of all my objects that this?(Using their memory addresses so I can access them easily still)?
Pass by reference.
Consider storing std::type_index http://en.cppreference.com/w/cpp/types/type_index
std::uintptr_t an unsigned integer type that can hold the value of an object pointer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cstdint>
#include <string>
#include <utility>
#include <typeinfo>
#include <typeindex>

template< typename UnknownObject >
std::pair< std::uintptr_t, std::type_index > generate_id( const UnknownObject& object ) // *** reference
{ return { std::uintptr_t( std::addressof(object) ), typeid(object) } ; }

int main()
{
    double dbl = 1234.56 ;
    std::cout << "object of type double at address " << std::addressof(dbl) << " has the value " << dbl << '\n' ;

    const auto id = generate_id(dbl) ;

    if( id.second == typeid(dbl) )
    {
        const double* p = reinterpret_cast<const double*>(id.first) ;
        std::cout << "object of type double at address " << p << " has the value " << *p << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/3f13b24d3658cea1
One problem I see is that at line 21 you're passing unknown by value, which means you have a temporary copy of the UnknownObject instance on the stack. At line 23, you take the address of this temporary object. id now contains the address of the temporary object. Line 27, this temporary object goes out of scope, invalidating id.

As pointed out by coder777, your solution is not portable. You will have problems if you switch to a 64 bit compiler.

I really question why you're trying to do this. Do you understand polymorphism? If you really want a unique identifier for each object, I would suggest making a base class that all your other classes derive from. Then a pointer to your base class will uniquely identify anything derived from your base class (and is a portable solution).
Last edited on
I'm not sure how a pointer to the base class would uniquely identify every object - wouldn't it always just point to that base class?
What I meant by that is that a pointer to any object derived from your base class would still be unique.

One thing you could do is have a virtual name function that would return the name of derived class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <string>
using namespace std; 

class Object
{
public: 
    virtual string Name () const = 0;
};

class Sword : public Object 
{
public:
    string name () const
    {   return "Sword";
    }
};

Last edited on
Topic archived. No new replies allowed.