简体   繁体   中英

Manually set pointer value

i'm working in C. What I'm trying to do is a function that will return an int containing an address pointing to an object. Then, use the int I received (containing the address), and build a pointer pointing to this address.

Example:

MyClass* obj = SomeMethodReturningAPointerOfMyClass();
int address = (int) &obj;
return address;

I think it works for this part. The value I get is -4197276. (Maybe I'm totaly wrong?)

Then, on the other part, I'd like to do something like:

MyClass* obj = (MyClass*) address;

which doesn't work as I can't access any method of obj without getting an error.


I found a way to do it:

MyClass* obj = SomeMethodReturningAPointerOfMyClass();
machine->registers[2] = (int)obj;

then, in the other method where I receive the integer I did:

MyClass* obj = (MyClass*)address;

I can work on the obj perfectly! Might not be so clean but it should do the job for what it's used for!

Thanks to everyone who took the time to answer!

First off, don't do this . You're getting the address of the pointer obj , not the object it points to. obj is already equal to that address. &obj will be some value on the stack (in your case, 0xFFBFF464 ) and it will become invalid when your function returns.

Second off, don't do this . An int is not the C or C++ type for a memory address--a pointer is, and you already have one.

An int is not the same as a MyClass * . In fact, on 64-bit systems (including most modern PCs), casting a pointer to an integer drops half the pointer's value, and the result is invalid.

If you want your function to return the address of an object, return the pointer:

MyClass *GetAnObject(void) {
    MyClass *result = ...;
    return result;
}

You should never need to convert a pointer to an integer (there are cases where it's valid, but for newcomers to C, a complete ban is simpler to understand; those edge cases are beyond the scope of this question.)

Apparently, since you are using classes, you are probably working in C++, not in C.

I really wonder why you actually want to store an object pointer in an int?

Regarding your question: depending on the platform, an (object) pointer may not fit in an int. If you cast the pointer to the int, you may simply truncate the pointer value. Now, if you cast back later, the pointer is not complete, and points to some undetermined spot in memory. That can cause problems.

In other words: don't do this. Not only is it very well possible that it fails, it can even cause a lot of problems.

First of all, you should use the unsigned long type instead of an int , as pointers are 32-bits wide (at least on 32-bit architecture; use unsigned long long if you want to be 64-bits aware).

Next, what you store in the address variable is not a MyClass* but a MyClass** as you store the address of obj using &obj when assigning to address ... (and obj is already of type MyClass* )

So you should either store directly the MyClass* pointer, or if you want to store the pointer of MyClass* , namely a MyClass** , you need to indirect it twice by using one more '*' to balance the '&' you wrote when affecting address :

MyClass* obj = * ((MyClass*)address);

&obj returns the address where the pointer obj is stored, which isn't quite what you want. The real answer is even simpler:

void *obj = SomeMethodReturningAPointerOfMyClass();
return (int) address;

Note that this'll break if int isn't the same size as a pointer on your system. You may want to pass this around as a void * , intptr_t , or long .

Depending on your system, int may be a poor choice. If you really have to pass the pointer as an integral value, you should use uintptr_t which is always guaranteed to be as big as a pointer.

Also, &obj is probably not what you want. I think you meant obj .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM