Как изменить адрес, на который указывает указатель в C ++ - PullRequest
0 голосов
/ 21 января 2019

Экспериментируя с указателями, у меня возникла идея сменить адрес на указатель. Я попробовал следующее:

int* pointer; 
&pointer = 0x28ff0d; //To point to an empty space in memory

Но это привело к ошибке (Подробности: (здесь) в строке 2, lvalue требуется как левый операнд [...]), так что я думаю, что это невозможно? Я не пытаюсь сделать нулевой указатель, но буквально изменить адрес памяти

Ответы [ 4 ]

0 голосов
/ 21 января 2019

int* pointer; &pointer = 0x28ff0d;

Это выдаст ошибку, потому что &pointer не является lvalue.С левой стороны от оператора присваивания должно быть lvalue.

0 голосов
/ 21 января 2019

Вы никогда не можете изменить адрес переменной. Поэтому, чем бы ни был T (является ли он внутренним типом, таким как int или double, структурой, указателем или массивом, в C ++ запрещено следующее:

T var;
&var = anything;   // WRONG! &var is not a lvalue

Ошибка lvalue, требуемая в качестве левого операнда , означает, что вы можете назначать только то, что может получить новое значение, а адрес переменной - нет.

0 голосов
/ 21 января 2019

Указатель является переменной.Любая переменная имеет адрес, по которому она находится.Поэтому, если вы объявили переменную, например, int x;, то &x - это адрес, где находится эта переменная.

Указатель - это переменная, которая находится где-то, но кроме того, она имеет значение, котороебывает адрес какой-то другой переменной.Так что если вы объявили указатель int* x;, написали что-то для него, то x будет представлять некоторый адрес, который вы написали ему, а *x будет значением, на которое указывает указатель.

Итак, ваша синтаксическая ошибка заключалась в использовании &, где вы должны были просто использовать имя переменной, без &.После того, как это станет ясно, обязательно прочитайте другие ответы, которые объясняют дальнейшие проблемы с вашим кодом.

0 голосов
/ 21 января 2019

По понятным причинам установка указателя на жестко закодированный адрес - плохая идея. Но вы можете сделать это, reinterpret_cast<> присвоив адрес типу, которому вы его назначаете, например:

int * pointer = reinterpret_cast<int *>(0xDEADBEEF);

или

int * pointer = &some_int;
. . .
pointer = reinterpret_cast<int *>(0xDEADBEEF);

Обратите внимание, что разыменование pointer в этом случае является неопределенным поведением ... но выполнение этого может все еще быть полезным для чего-то вроде отладки use-after-free, где значение часового элемента, такое как 0xDEADBEEF, ясно сообщило бы, что вы уже освободили эта память.

Очевидно, что гораздо более распространенным, полезным и безопасным случаем для изменения адреса, на который вы указываете, было бы использование адреса другого (реального) фрагмента данных:

int * pointer = &some_int;
int new_val = 1234;
pointer = &new_val; // *pointer is now 1234
...