C访问内存位置

C访问内存位置,c,memory,C,Memory,我指的是物理内存,RAM 在C语言中,您可以访问任何内存地址,那么操作系统如何防止程序更改不在程序内存空间中的内存地址呢 它是否为每个程序设置了特定的内存地址作为开始和结束,如果是,它如何知道需要多少内存。实际上,您的程序分配了虚拟内存,这就是您所使用的。操作系统为您提供了RAM的一部分,您无法访问其他进程的内存(除非它是共享内存,请查找)。这取决于体系结构,在某些情况下,甚至无法防止程序崩溃系统,但一般来说,平台提供了一些方法来保护不同进程的内存和单独的地址空间。当硬件和操作系统都支持内存管理

我指的是物理内存,RAM

在C语言中,您可以访问任何内存地址,那么操作系统如何防止程序更改不在程序内存空间中的内存地址呢


它是否为每个程序设置了特定的内存地址作为开始和结束,如果是,它如何知道需要多少内存。

实际上,您的程序分配了虚拟内存,这就是您所使用的。操作系统为您提供了RAM的一部分,您无法访问其他进程的内存(除非它是共享内存,请查找)。

这取决于体系结构,在某些情况下,甚至无法防止程序崩溃系统,但一般来说,平台提供了一些方法来保护不同进程的内存和单独的地址空间。

当硬件和操作系统都支持内存管理(MMU)硬件时,您的操作系统内核与内存管理(MMU)硬件密切配合,使您无法访问被禁止访问的内存

一般来说,这也意味着您访问的地址不是物理地址,而是虚拟地址,硬件执行适当的转换以执行访问。

操作系统执行“内存管理”,通常与TLB(转换查找缓冲区)和虚拟内存相结合,将任何地址转换为页面,操作系统可以在当前进程上下文中将其标记为可读或可执行


处理器MMU或内存管理单元的最低要求是,在当前上下文中,将可访问内存限制在一个范围内,该范围只能在管理模式(与用户模式相反)下的处理器寄存器中设置。

这与CPU本身提供的一种称为“分页”的功能有关。在旧的操作系统中,有“实模式”,可以直接访问内存地址。相反,分页提供了“虚拟内存”,因此您不会访问原始内存本身,而是访问程序认为是整个内存映射的内容。

这就是所谓的内存保护。它可以使用不同的方法来实现。我建议您从Wikipedia关于这个主题的文章开始-

逻辑地址由CPU生成,由内存映射单元映射到物理地址。与物理地址空间不同,逻辑地址不受内存大小的限制,您只需使用逻辑地址空间即可。地址绑定由MMU完成。因此,您从不直接处理物理地址

大多数计算机(以及386之后的所有PC)都有一种称为内存管理单元(MMU)的设备。它的工作是将程序使用的本地地址转换为从实际内存中获取实际字节所需的物理地址。对MMU进行编程是操作系统的工作

因此,可以将程序加载到内存的任何区域,并从该程序执行时的角度来看,显示为任何其他地址。通常会发现,所有程序的代码(本地)都位于同一地址,并且它们的数据(本地)总是位于同一地址,即使它们在物理上位于不同的位置。每次访问内存时,MMU都会透明地从本地地址空间转换为物理地址空间

如果程序试图访问尚未映射到其本地地址空间的内存地址,则硬件会生成异常,通常会标记为“分段冲突”,然后强制终止程序。这可以防止访问其他进程的内存

但事实并非如此!在具有“虚拟内存”且当前RAM资源需求超过物理内存量的系统上,某些页面(通常为4-8kB大小的内存块)可以写入磁盘,并作为RAM提供给试图分配和使用新内存的程序。稍后,当拥有该页的任何程序都需要该页时,内存访问会导致异常,操作系统会调出一些其他内存页,并从磁盘重新加载所需的内存页。发生这种情况时,“页面出错”的程序会延迟,但在其他情况下不会注意到任何内容


MMU/OS还可以做很多其他的技巧,比如在进程之间共享内存,使磁盘文件看起来可以直接访问内存,将某些页面设置为“NX”,这样它们就不能被视为可执行代码,使用逻辑内存空间的任意部分,而不管物理ram使用多少和使用什么地址,还有更多。

请搜索“虚拟内存”一词,它是一个相当广泛的主题,取决于一堆东西(主要是CPU、操作系统)。好的,请不要投反对票,因为我对所有这些都不太了解。不,在C中,你不能访问任何内存地址。指针只有在它是对象的地址时才有效。@Apeee好吧,只是一个注释(不要计划向下投票)-仅仅因为你对此不太了解,并不意味着向下投票无效。:)否则,任何问题都不会被否决。我认为@KerrekSB谈论的是c标准(我不确定是否适用)。事实上,问题不在于语言。是的。。。我想有人在试图平息竞争:)我想是的,但我只希望有一个答案不会被否决:)