与 C 中的指针和虚拟内存混淆

标签 c operating-system virtual-memory

我想我的问题很简单,但我找不到答案。 根据我对虚拟内存的理解:

every process receives a contiguous address space which is mapped to physical memory.

因此,我在我的程序中编写的代码应该能够访问分配给它的虚拟内存中的任何位置,因此我在 C 中编写了以下代码,它抛出了“访问冲突异常”类型的异常。

如果有人向我解释原因,我将不胜感激。

代码如下:

int* a = 1; // pointer to 1st block of memory
*a = 5; // set the content of pointer to 5, but throws exception

最佳答案

每个进程都会收到一个连续的逻辑地址空间。不是连续的 VIRTUAL 地址空间。

逻辑页面映射到物理页面框架。

逻辑映射是使用 PAGE TABLE 完成的,包含从本地页面到页面框架的映射。

但是,页表可能不会为每个逻辑页都映射到一个页框。

发生这种情况的原因有两个。首先,操作系统可能不会(通常不会)创建跨越整个地址空间的页表条目。系统参数或进程配额可能会限制逻辑地址空间的大小。一些系统还会将地址范围保留为不可用。

其次,必须有人做逻辑页面的映射。这是一个两步过程。 (1) 某人(通常是加载程序)必须将逻辑页面标记为有效。 (2) 操作系统必须将逻辑页映射到物理页。这是在进程访问没有映射的有效逻辑页面时完成的,从而导致页面错误。 (即虚拟内存——有效逻辑页面到页面框架的动态重新映射)。

一个页表条目可以有三种状态:

  1. 无效
  2. 它是有效的并且映射到一个映射页面框架
  3. 它有效但没有映射到物理页面框架。 (同样,如果在此状态下访问页表条目,则会触发 PAGE FAULT,导致操作系统创建到有效页框的映射。)

在运行时,应用程序可以调用系统服务使逻辑页在逻辑地址空间中有效。

作为捕获杂散指针的安全检查,大多数系统(通常由链接器指示)根本不映射第一页(但是,应用程序通常可以通过系统调用映射页面)。你的:

 int *a = 1 ;

将“a”的地址设置为第一页中的位置,该位置始终无效。

你的

*a = 5 ;

使处理器(内存翻译单元)访问第一页的页表条目。在那里,处理器发现这个页表条目被标记为无效(即没有可能的映射)。这会导致访问冲突。

关于与 C 中的指针和虚拟内存混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35620267/

相关文章:

c - 0xC0000005 : Access violation reading location 0x00000008. C代码

c - Postgresql C 函数,不加载外部 dll 文件

Windows 大页面支持 2MB 以外的吗?

c - C 中的拼写检查器

c - 以 N 为基数的除法

Java 不阻塞 I/O 的最佳默认线程数

linux - 当操作系统等待用户输入时,CPU 是否仍在执行任何指令?

c++ - 用户空间栈和堆的内存布局

linux - 为什么 Linux (x86) 的页面大小是 4 KB,这是如何计算的?

windows - 对大型内存映射文件的高效稀疏访问