Установите значение указателя вручную - PullRequest
0 голосов
/ 17 июля 2011

Я работаю в 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 ]

6 голосов
/ 17 июля 2011

Прежде всего, не делайте этого .Вы получаете адрес указателя obj, а не объект, на который он указывает.obj уже равен этому адресу.&obj будет некоторым значением в стеке (в вашем случае, 0xFFBFF464) и станет недействительным, когда ваша функция вернется.

Снова, не делайте этого .int не является типом C или C ++ для адреса памяти - указатель есть, и он у вас уже есть.

int - это не то же самое, что MyClass *.Фактически, в 64-битных системах (включая большинство современных ПК) приведение указателя к целому числу приводит к уменьшению половины значения указателя, и результат является недействительным.

Если вы хотите, чтобы ваша функция возвращала адресobject, верните указатель:

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

Вам никогда не нужно преобразовывать указатель в целое число (есть случаи, когда он действителен, но для новичков в C полный бан проще понять;случаи выходят за рамки этого вопроса.)

1 голос
/ 17 июля 2011

Видимо, поскольку вы используете классы, вы, вероятно, работаете в C ++, а не в C.

Мне действительно интересно, почему вы на самом деле хотите хранить указатель на объект в int?

По вашему вопросу: в зависимости от платформы указатель (объекта) может не помещаться в int. Если вы приведете указатель на int, вы можете просто обрезать значение указателя. Теперь, если вы вернётесь позже, указатель не завершён и укажет на какое-то неопределённое место в памяти. Это может вызвать проблемы.

Другими словами: не делай этого. Мало того, что вполне возможно, что он потерпит неудачу, он может даже вызвать много проблем.

0 голосов
/ 17 июля 2011

В зависимости от вашей системы, int может быть плохим выбором. Если вам действительно нужно передать указатель как целое значение, вы должны использовать uintptr_t, который всегда гарантированно будет таким же большим, как указатель.

Кроме того, &obj, вероятно, не то, что вы хотите. Я думаю, что вы имели в виду obj.

0 голосов
/ 17 июля 2011

&obj возвращает адрес, на котором хранится указатель obj, что не совсем то, что вам нужно. Реальный ответ еще проще:

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

Обратите внимание, что это сломается, если int не соответствует размеру указателя в вашей системе. Вы можете передать это как void *, intptr_t или long.

0 голосов
/ 17 июля 2011

Прежде всего, вы должны использовать тип unsigned long вместо int, так как указатели имеют ширину 32 бита (по крайней мере, для 32-битной архитектуры; используйте unsigned long long, если вы хотите быть 64-битным известно).

Затем, что вы храните в переменной address, это не MyClass*, а MyClass**, поскольку вы сохраняете адрес obj , используя &obj при назначении address .. . (и obj уже имеет тип MyClass*)

Таким образом, вы должны либо напрямую сохранить указатель MyClass*, либо, если вы хотите сохранить указатель MyClass*, а именно MyClass**, вам нужно дважды указать его, используя еще одну '*', чтобы сбалансировать '&' вы написали, когда затрагивали address:

MyClass* obj = * ((MyClass*)address);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...