Доступ к адресу памяти вручную

Есть ли способ получить доступ к адресу памяти вручную без использования указателей или ссылок? Допустим, я знаю, что целое число хранится по адресу 0x28fed8, и я хочу распечатать эти данные. Я пробовал std::cout << (int*)0x28fed8, но он просто выводит 0x28fed8. Также он работает, когда я назначаю адрес указателю, подобному этому int* w1= (int*)0x28fed8; для целого числа, но дает странный результат для переменной типа double (2.22064e-313)

#include <iostream>

int main(){
   int a=10;
   int* w1= (int*)0x28fed8;

   double b=100.578;
   double* w2= (double*)0x28fed0;

   std::cout << &a << std::endl;  // output 0x28fed8
   std::cout << *w1 << std::endl; // output 10

   std::cout << (int*)0x28fed8 << std::endl; // output 0x28fed8

   std::cout << &b << std::endl;  // output 0x28fed0
   std::cout << *w2 << std::endl; // output 2.22064e-313

   return 0;
}

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


person user50533    schedule 02.08.2014    source источник
comment
Как узнать, что int находится в 0x28fed8?   -  person David C. Rankin    schedule 02.08.2014
comment
Откуда вы знаете, что 0x28fed0 действительно является адресом двойного b?   -  person vsoftco    schedule 02.08.2014
comment
Разве это не должно быть: std :: cout ‹* * ((int *) 0x28fed8) ‹< std :: endl; ? Внешняя скобка может и не понадобиться, но ее легче читать.   -  person rcgldr    schedule 02.08.2014
comment
Какая от этого польза, если вы не используете встроенное устройство с четко определенной картой памяти?   -  person Fiddling Bits    schedule 08.08.2014


Ответы (1)


Если вы хотите распечатать значение целого числа по определенному адресу, вам нужно сделать

std::cout << *(int *)0x28fed8 << std::endl;

Таким образом, вы разыменовываете указатель вместо того, чтобы печатать само значение указателя.

Что касается того, что ваше двойное значение неверно, я подозреваю, что это связано с оптимизацией компилятора. Ваш указатель w2 разыменовывается до того, как переменная b записала свое значение. Если это правда, вам просто повезло с a и w1.

Что, если вы переместите переменные b и a в глобальную переменную или пометите их как статические? Это должно гарантировать, что значение будет установлено к моменту разыменования указателей, поскольку оно, вероятно, будет жестко закодировано во время компиляции.

В противном случае попробуйте сделать указатели изменчивыми, то есть volatile double *w2 и volatile int *w1, чтобы компилятор не пытался оптимизировать.

(Я должен упомянуть, что в целом ваш код кажется довольно изворотливым с самого начала. Однако я не совсем уверен, вызывает ли он неопределенное поведение - возможно, некоторые другие пользователи могут пролить свет на это)

person tangrs    schedule 02.08.2014
comment
Спасибо. Я добавил переменную вместо константы в качестве значения адреса, и теперь он произвольно печатает материал из своей памяти. - person John; 13.03.2019