Установите значение указателя вручную
Я работаю в C. Я пытаюсь сделать функцию, которая будет возвращать int, содержащий адрес, указывающий на объект. Затем используйте полученный int (содержащий адрес) и создайте указатель, указывающий на этот адрес.
Пример:
MyClass* obj = SomeMethodReturningAPointerOfMyClass();
int address = (int) &obj;
return address;
Я думаю, что это работает для этой части. Значение, которое я получаю, составляет -4197276. (Может я совершенно не прав?)
Затем, с другой стороны, я хотел бы сделать что-то вроде:
MyClass* obj = (MyClass*) address;
который не работает, так как я не могу получить доступ к любому методу obj без получения ошибки.
Я нашел способ сделать это:
MyClass* obj = SomeMethodReturningAPointerOfMyClass();
machine->registers[2] = (int)obj;
затем в другом методе, где я получаю целое число, которое я сделал:
MyClass* obj = (MyClass*)address;
Я могу работать на объекте отлично! Может быть, не такой чистый, но он должен делать то, для чего он используется!
Спасибо всем, кто нашел время, чтобы ответить!
5 ответов
Во-первых, не делай этого. Вы получаете адрес указателя obj
, а не объект, на который он указывает. obj
уже равен этому адресу. &obj
будет какое-то значение в стеке (в вашем случае, 0xFFBFF464
) и он станет недействительным, когда ваша функция вернется.
Во-вторых, не делай этого. int
это не тип C или C++ для адреса памяти - указатель есть, и он у вас уже есть.
int
это не то же самое, что MyClass *
, Фактически, в 64-битных системах (включая большинство современных ПК) приведение указателя к целому числу приводит к уменьшению половины значения указателя, и результат является недействительным.
Если вы хотите, чтобы ваша функция возвращала адрес объекта, верните указатель:
MyClass *GetAnObject(void) {
MyClass *result = ...;
return result;
}
Вам никогда не нужно преобразовывать указатель в целое число (в некоторых случаях он действителен, но для новичков в C полный бан проще понять; эти крайние случаи выходят за рамки этого вопроса).
Очевидно, поскольку вы используете классы, вы, вероятно, работаете в C++, а не в C.
Мне действительно интересно, почему вы на самом деле хотите хранить указатель на объект в int?
Относительно вашего вопроса: в зависимости от платформы указатель (объекта) может не помещаться в int. Если вы приведете указатель на int, вы можете просто обрезать значение указателя. Теперь, если вы вернётесь позже, указатель не будет завершён и укажет на какое-то неопределённое место в памяти. Это может вызвать проблемы.
Другими словами: не делай этого. Мало того, что вполне возможно, что он потерпит неудачу, это может даже вызвать много проблем.
&obj
возвращает адрес где указатель obj
хранится, что не совсем то, что вы хотите. Реальный ответ еще проще:
void *obj = SomeMethodReturningAPointerOfMyClass();
return (int) address;
Обратите внимание, что это сломается, если int
не такой же размер, как указатель в вашей системе. Вы можете передать это как void *
, intptr_t
, или же long
,
В зависимости от вашей системы, int
может быть плохой выбор. Если вам действительно нужно передать указатель как целое значение, вы должны использовать uintptr_t
который всегда гарантированно будет таким же большим, как указатель.
Также, &obj
это, вероятно, не то, что вы хотите. Я думаю ты имел ввиду obj
,
Прежде всего, вы должны использовать unsigned long
введите вместо int
, поскольку указатели имеют ширину 32 бита (по крайней мере, для 32-битной архитектуры; используйте unsigned long long
если вы хотите быть в курсе 64-бит).
Далее, что вы храните в address
переменная не является MyClass*
но MyClass**
как вы храните адрес объекта с помощью &obj
при назначении address
... (а также obj
уже типа MyClass*
)
Таким образом, вы должны либо хранить непосредственно MyClass*
указатель, или если вы хотите сохранить указатель MyClass*
а именно MyClass**
, вам нужно сделать это дважды, используя еще одну '*', чтобы сбалансировать написанное вами "&" при address
:
MyClass* obj = * ((MyClass*)address);