Jump to content

Convert object to integer and back


Josh
 Share

Recommended Posts

I can convert an object to an integer as follows:

Object* o;
int pointer = *(int*)o;

What is the reverse operation to get an object from an integer?

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

You are not creating the object at all, but you only declare a pointer to the object.

So you should either get rid of the * or use new Object()

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

If I read into what you are thinking, it seems like you want to take the pointer as some kind of ID for the object since it should be unique (since it's a memory address) and convert it to int to be passed back and forth between C++ & Lua?

Link to comment
Share on other sites

In theory, this works:

Object* o= (Object*)&pointer;

 

But the program says the second pointer is not the same as the original.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

From what I've read (random articles online) the size of a pointer isn't guaranteed on different systems. I've also read something about some front bits on certain systems for pointers are treated differently than for an int. Anyway, the following works for me, but I still think it's risky.

 

#include <string>
#include <iostream>

using namespace std;

class Object
{
private:
string name;
public:
Object(string n)
{
	name = n;
}
void Test()
{
	cout << name;
}
};


int main()
{
Object* obj = new Object("test");

int ptr = (int)obj;

Object* o = (Object*)ptr;

o->Test();   // this does indeed print out "test" which means it's the same object that I created in the first line

       // just make it so the window doesn't close right away
int w;
cin >> w;

return 0;
}

 

Your problem was most likely:

 

int pointer = *(int*)o;

 

You don't want to cast it to an (int*) but just an int.

 

 

Don't blame me if this doesn't work on every system you are trying to target though :)

Link to comment
Share on other sites

I think he wants unique numbers for each unique object. He could do it using some int id attribute too, and int operator==() which returns the id of the object. When the id is the same, it's the same object. When the id is different, then the object is a different instance of the class

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I think he wants unique numbers for each unique object. He could do it using some int id attribute too, and int operator==() which returns the id of the object. When the id is the same, it's the same object. When the id is different, then the object is a different instance of the class

If that's the case I can agree with you. Use a ID attribute instead and don't mess with the pointers.

AV MX Linux

Link to comment
Share on other sites

Object* o;
int pointer = *(int*)o;

 

When doing this, you only store the first 4 Bytes of your Object data (not the pointer to the object!) in the pointer-variable.

There is no way to get back the original object from this int, because you do not store the adress of you object anywhere.

 

If you do:

int pointer = (int)o;

it might work, but only if the size of int matches the size of a pointer. This is not the case on x64 systems.

Link to comment
Share on other sites

I don't really understand what you are after but this approach makes a unique id for each object and is safe

 

#include <iostream>

using namespace std;

class MyClass
{
   static unsigned int _id;
   unsigned int _myid;

   public:
       MyClass(void)
       {
           _myid = _id++;
       }

       bool operator == ( const MyClass& c ) const
       {
           return _myid == c.getID();
       }

       unsigned int getID(void) const
       {
           return _myid;
       }
};
unsigned int MyClass::_id = 0;

int main()
{
   MyClass a;
   MyClass b;
   MyClass* p = &a;

   cout << "a is " << (a==b?"":"NOT") << " b" << endl;
   cout << "*p is " << (*p==b?"":"NOT") << " b" << endl;
   cout << "a is " << (*p==a?"":"NOT") << " *p" << endl;
   cout << "a id = " << a.getID() << endl;
   cout << "b id = " << b.getID() << endl;
   cout << "*p id = " << p->getID() << endl;

   return 0;
}

 

 

a is NOT b

*p is NOT b

a is *p

a id = 0

b id = 1

*p id = 0

 

Process returned 0 (0x0) execution time : 0.053 s

Press any key to continue.

AV MX Linux

Link to comment
Share on other sites

That's how I would do it too, except for the few naming inconsistencies (first letter of method always Big, no underbars in front of attribute names).

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

That's how I would do it too, except for the few naming inconsistencies (first letter of method always Big, no underbars in front of attribute names).

Forgot to write the sample in accepted standard style.

Used my own personal touch there. Sorry about that.

AV MX Linux

Link to comment
Share on other sites

If pointer size isn't the same on either system isn't enough to scare you away, here is another fear that could happen. Note the obj gets deleted and even with a NULL check it still goes into and tries to run the Test() function. So if passing things between Lua and C++ this could happen to someone.

 

#include <string>
#include <iostream>

using namespace std;

class Object
{
private:
string name;
public:
Object(string n)
{
	name = n;
}
void Test()
{
	cout << name;
}
};


int main()
{
Object* obj = new Object("test");

int ptr = (int)obj;

delete obj;

Object* o = (Object*)ptr;

if(o != NULL)
	o->Test();           // it will still try to run this and fail

int w;

cin >> w;

return 0;
}

Link to comment
Share on other sites

The only time I've done anything like this two way casting is when passing generic type pointers to functions where I've used void pointers for the parameter and passed the type as a string. The void pointer is then cast back to its original type and this works well.

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

I agree, just don't mess with pointers. I would even say to not mess with raw pointers, use the way better unique, shared and weak pointers from C++11...

The proposition made by Roland is by far the best, except for a possible thread safety issue (and Roland, there is no universal or accepted C++ standard... I go more for your design as far Lumooja's which I think is just plain evil :)).

 

But the big question here is, what is the idea? If this is based on stack semantics this is wrong! Take for example:

std::string one("Test string");
std::string two("Test string");

one == two is true, but they don't point to the same memory block... The concept of stack based development is value semantics, not pointer semantics.

 

Josh, what are you doing? Way better to comment that way :)!

 

The only time I've done anything like this two way casting is when passing generic type pointers to functions where I've used void pointers for the parameter and passed the type as a string. The void pointer is then cast back to its original type and this works well.

 

If you have void pointers there is something wrong with your design :). Don't take this wrong, even Microsoft uses it, and you can. But this doesn't mean you should... With some base class you can get as far...

Link to comment
Share on other sites

If you have void pointers there is something wrong with your design :). Don't take this wrong, even Microsoft uses it, and you can. But this doesn't mean you should... With some base class you can get as far...

 

For me personally it's about wanting more dynamic functionality that C++ doesn't provide. If C++ had reflection then there would probably be no need for void* when looking to have the ultimate flexibility. I have a million uses with .NET reflection. I can do it all with C++ but it's slightly less flexible. I love being able to create a class and call it's function all from string variables!

Link to comment
Share on other sites

For me personally it's about wanting more dynamic functionality that C++ doesn't provide. If C++ had reflection then there would probably be no need for void* when looking to have the ultimate flexibility. I have a million uses with .NET reflection. I can do it all with C++ but it's slightly less flexible. I love being able to create a class and call it's function all from string variables!

 

I do not really agree with you. A strong typed language isn't supposed to be used like that, and I find using reflection rather a bad practice. I even use it, but the problem with this is it's going to be mis or/and over used. Take LINQ for example, this had a great boost but now more and more developers are saying they used it where they didn't had to, making it hard to debug, ... If you really want to use them, use languages such as Python which have been designed for. I even think C++ will never provide this support, this would enforce a string standard, ...

Link to comment
Share on other sites

I'm actually storing the object in a map, looked up by the hex address, but I like to display the hex address because it can be verified in any programming language. I always found it weird how C++ programmers are so scared of this idea. It's just a block of RAM.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...