繁体   English   中英

在C中,在Linux中工作,何时超出范围访问数组会导致段错误?

[英]In C, working in Linux, when will accessing arrays out of bounds cause a seg fault?

如果我在Linux(和Windows,也许还有所有东西,但我应该清楚)中访问数组,则有时可以在那里访问内存,有时可以立即进行段错误。 我想知道段错误的条件是什么,为什么不一直触发它? 这是我的猜测,如果有人可以确认或拒绝:

内存以页面粒度分配给进程,这在x86上为4KiB(无论如何是32位,不确定大约64位)。 因此,从理论上讲,只要我停留在当前页面内,我就应该能够访问数组之外​​的任何内容,并且甚至不会引发异常。

接下来,如果我超出4KiB边界访问,这可能是我在访问已属于程序,并很好地映射到实际的物理存储位置在我的虚拟地址空间中的内存。 再一次,因为该内存最初是我的,所以没有发生任何问题(嗯,发生问题的原因是我访问的范围超出限制,但是没有发生操作系统异常)。

在另一方面,如果我的数组访问试图访问我的进程的限制内核部分,我明白即使它映射到物理内存的内存段错误的异常。

最后,如果我要访问虚拟地址空间中存在的内存,但还没有物理内存,则有两种情况:

1)我非常不幸,我碰巧要处理一块内存,该内存在二级存储中存在一个有效页面,因此页面错误异常只会加载新页面,而且我可以继续访问

2)更有可能,我尝试在没有有效页的虚拟地址空间中访问一块内存,因此现在MMU抛出seg错误。

是这样吗? 还有更多条件吗?

您涵盖了大部分内容。 我能想到的唯一其他事情与一般保护错误有关,例如:您越过了页面边界,即使该页面有效且已映射,它也未标记为可读/可写,该页面包含代码而非数据,等等。 ...

发生了一系列的事件。 作为C编程语言(及其派生语言)的可憎性不对数组进行范围检查。

(现在假设您正在进行数组边界之外的访问)

因为内存管理基于页面,所以只要您不越过页面边界,任何东西都可以以阵列实际内存允许的任何方式访问内存。

如果确实超过页面边界,则处理器必须转到页面表

  1. 该页面可能没有页面表条目。 =>访问冲突
  2. 该页面可能有一个页面表条目,并且未映射。 =>访问冲突
  3. 该页面可能被限制为更高的访问模式(例如,内核,主管,主管)。 如果是这样,则=>访问冲突。
  4. 您可以尝试以不允许的方式访问该页面(例如,写入只读页面)。 如果是,则=>访问冲突

如果您尝试访问的逻辑页面具有映射,并且您尝试以允许的方式访问它,那么您可以将自己挂在C中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM