为什么我可以增加指针来读取已分配变量的长度,操作系统不会阻止我?当然,因为它是为整数留出4个字节的那个,它应该知道它不应该允许任何指针超过这4个字节吗?
实际上,当我将指针递增超过变量的已分配字节时,我究竟在读什么/那些相邻的内存位置?而且由于每个程序都应该拥有自己的地址空间",我不能在那个地址空间内做任何我想要的事情"没有段错误?如果每个程序都有自己的地址空间,那么读取属于其他程序的内存应该是不可能的,对吗?
答案 0 :(得分:3)
我注意到这个问题是我昨天博客的主题。见http://ericlippert.com/2014/05/07/why-does-my-code-not-crash
为什么我可以增加指针来读取已分配变量的长度,操作系统不会阻止我?
出于同样的原因,操作系统不会让你成为火腿三明治!没有人在操作系统中写入火腿三明治功能,因此不会发生这种行为。未实现的功能未实现。阻止您这样做不是您正在使用的操作系统的功能。
当然,因为它是为整数留出4个字节的那个,它应该知道它不应该允许任何指针超过这4个字节吗?
不。通常,操作系统将地址空间放在名为 pages 的4KB块中。
实际上,当我将指针递增到变量的已分配字节时,我究竟在读什么?那些相邻的内存位置?
是。它们与虚拟内存位置相邻。
因为每个程序都应该有自己的“地址空间”,所以我不能在没有段错误的“地址空间”内做任何我想做的事情吗?
没有。您可以在地址空间中执行任何已虚拟分配的地址。请注意,许多操作系统允许您在页面上添加其他约束,例如“此页面可以从中读取但不能写入或执行”。在这些情况下,读取不会导致错误,但会写入。
如果每个程序都有自己的“地址空间”,那么读取属于其他程序的内存是不可能的,对吗?
这不是不可能,但它通常是故意。在许多操作系统中,两个进程可以同时将磁盘上文件的同一页映射到虚拟内存中,从而共享内存。
回到虚拟内存前几天,像Windows 3这样的操作系统会让两个进程写入彼此的内存没问题,但现在几十年来情况并非如此。
答案 1 :(得分:0)
编译器可以执行此操作,但它选择不执行此操作,因为如果您为每个内存访问执行此操作,则运行时开销会造成严重的性能损失。
某些编译器提供了一个选项,可以在调试时启用此检查。
Eric Lippert的评论回答了你的第二段。