【问题标题】:confusion with pointers and virtual memory in C与 C 中的指针和虚拟内存混淆
【发布时间】:2016-06-07 19:29:30
【问题描述】:

我认为我的问题很简单,但我找不到答案。 基于我对虚拟内存的理解:

每个进程都会收到一个连续的地址空间,该地址空间映射到 物理内存。

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

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

代码如下:

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

【问题讨论】:

  • 你不能写入你不拥有的内存。一部分地址空间被保留(未映射)
  • 谁说你所有的记忆都是可写的?另外,为什么你认为它保持连续?
  • every process receives a contiguous address space which is mapped to physical memory 这是操作系统问题,取决于其内存处理。 following code in C which throws an exception 这是C 代码问题。 C 标准不了解您可能想到的特定操作系统,也无法解决该部分。就C 标准而言,您没有以某些C 标准方式(例如malloc,或定义变量)获得的内存在实际用途中不存在,并导致UB(未定义行为)如果访问。

标签: c operating-system virtual-memory


【解决方案1】:

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

逻辑页映射到物理页帧。

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

但是,页表可能没有到每个逻辑页的页框的映射。

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

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

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

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

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

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

 int *a = 1 ;

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

你的

*a = 5 ;

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

【讨论】:

  • 逻辑地址不是虚拟地址的同义词吗?否则一个很好的答案。如果您提到这与在物理内存不足时将页面交换到磁盘的关系,可能会更好。
  • 不,虚拟和逻辑是两个相关但不同的概念。
【解决方案2】:

整个地址空间没有映射到物理内存,只有部分。您不能使用未映射的地址。

通常地址空间的一部分是为操作系统保留的。地址空间的一部分可以映射到文件,其他的可以映射到硬件设备。拥有“虚拟”内存系统的整个想法是,您可以使用单个地址空间来引用多个事物,这也意味着并非所有虚拟地址始终都是“有效”的。

【讨论】:

  • 它的哪些部分?你有更多信息的链接吗?
  • 查找地址映射是特定于操作系统的。例如,Linux 内核在 /proc/self/maps 中公开此信息。
猜你喜欢
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
  • 2014-11-18
  • 2016-07-09
  • 2011-11-29
  • 2017-07-25
  • 2018-04-22
  • 2010-09-25
相关资源
最近更新 更多