我能访问内存中的任何内容吗?

时间:2012-10-09 17:41:46

标签: c pointers memory-management

免责声明:我是C / C ++的新手。

如果我manually assign a memory address转到C中的变量,然后尝试回显该值...我是否可以无限制地访问内存中的任何或是否存在限制在哪里?

例如:

char * p = (char *)0x28ff44;
printf("Memory value: %c", *p);

我猜如果该地址的内容不符合char类型的大小,那将会崩溃,但这只是一个例子。我真正感到好奇的是,如果这样的事情是可能的,或者操作系统是否施加限制并且只允许您访问给定内存空间中的内存?

4 个答案:

答案 0 :(得分:5)

哦,我的,好吧。

技术上,是的,你可以。在不使用MMU或任何形式保护的嵌入式设备中(或者,您知道,x86在实模式下),您可以完全按照您在那里发布的内容进行操作。您也可以在任何操作系统上以用户模式执行此操作,但实际访问有效内存的可能性非常小。

实际上,不,你不能这样做。鉴于虚拟内存和内存保护,您尝试访问的区域很可能不会被映射,因此会失败。此外,如果您点击受保护的内存(例如属于操作系统的任何内容),您的访问权限将失败。这两种情况都会导致分段错误。

您的陈述有效(对于有效的不同定义),程序将尝试访问您请求的内存。只是它可能实际上没有映射到任何东西。

值得注意的是,这是内存映射I / O的工作原理。假设我有一个硬件控制寄存器,当写入时,在连接的UART /串行线上写一个字节(为简单起见,它可以像魔术一样工作,不需要设置任何其他寄存器)。在C中,对于我过度简化的设备,这将写成如下:

#define UART1_OUT 0xFC56   

volatile char* uart = UART1_OUT;   // Definition of pointer to variable.
                                   // volatile is required here. Look it up, but
                                   // it basically stops your compiler optimising
                                   // anything to do with this variable

*uart = 'A';                       // Write an A character to the serial line

当然,真实世界的设备稍微复杂一些;)。

答案 1 :(得分:2)

这取决于程序运行的计算机体系结构和操作系统。现代操作系统具有protectedvirtual内存的概念。对于虚拟内存,内存地址不是指物理内存,而是指分配给当前应用程序的虚拟内存空间。在这些情况下,尝试读取或写入分配的存储空间之外的存储器将导致程序故障(通常是分段故障或保护故障)。

答案 2 :(得分:1)

具有内存管理单元(MMU)的系统很可能不允许您访问任意内存。任何现代OS都使用内存保护。但是在嵌入式领域,有许多操作系统没有采用内存保护,并且确实可以访问任何可地址内存。

答案 3 :(得分:1)

  

如果我要手动为C中的变量分配一个内存地址,和   然后尝试回应那个价值......我是否可以无限制地访问   查看内存中的任何内容或是否存在限制?

C语言很乐意让您尝试,但大多数操作系统都不允许您访问进程内存空间之外的内存。如果您正在为嵌入式系统编写代码,而代码和硬件之间的代码不多,那么您可能可以读取和写入您喜欢的任何位置。但是,如果你正在为具有受保护内存的系统编写代码,那就不那么重要了。

  

我猜测如果在那个地址发生什么事情就会崩溃   不符合char类型的大小

Nah ......编译器不关心在任何给定地址存储什么类型的数据。当你说(char *)0x28ff44时,你告诉它0x28ff44char *,这对于编译器来说已经足够了。但是,您的代码可能仍会因其他原因而崩溃,例如0x28ff44不是有效地址。