手动访问内存地址

Access memory address manually

本文关键字:地址 内存 访问      更新时间:2023-10-16

是否有一种方法可以手动访问内存地址而不使用指针或引用?假设我知道这个整数存储在地址0x28fed8,我想打印这个数据。我试过std::cout << (int*)0x28fed8,但它只输出0x28fed8。当我将地址分配给像int* w1= (int*)0x28fed8;这样的指针时,它也可以工作,但对于双变量(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;
}

当然,当我测试它的结果是准确的-它可能会给出不同的输出当有人试图编译代码

如果要打印特定地址处的整数值,则需要执行

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

你是在解引用指针,而不是打印指针本身的值。

至于你的双精度值是错误的,我怀疑这与编译器优化有关。在b变量的值被写入之前,w2指针被解引用。如果这是真的,你只是碰巧有aw1

如果您将ba变量移到全局变量或将它们标记为静态,该怎么办?这将确保在指针解引用时设置该值,因为它很可能在编译时被硬编码。

否则,尝试使你的指针易变-即volatile double *w2volatile int *w1,这样编译器就不会尝试优化。

(我应该提一下,总的来说,你的代码一开始就很不可靠。但是,我实际上不确定它是否调用了未定义的行为-也许其他一些用户可以阐明这一点)

为了获得更清晰的方法,您可以考虑使用reinterpret_cast<>和某种形式的封装。

reinterpret_cast<比;您可以这样访问您的地址:>

#define LOCATION 0x28fed8
*reinterpret_cast<DWORD64*>(LOCATION) = 1;
为了更简洁的代码和编译器优化,我会将内存访问指令封装到一个匿名命名空间内的volatile函数中,例如:
namespace {
    volatile DWORD& memory(const DWORD location) {
        return *reinterpret_cast<DWORD64*>(location);
    }
}

,然后设置内存位置:

memory(LOCATION) = 1;

或者用:

std::cout << memory(LOCATION);