为什么 Linux 指针越界时程序会立即被中断，而 Windows 不会？
所谓访问越界指针其实就是访问非法内存地址。众所周知，操作系统内存管理的重要概念就是虚拟内存，每个独立的进程都在逻辑上可以拥有一整片巨大的连续的逻辑地址空间，但是实际上逻辑地址的背后却是捉襟见肘的实际物理内存的物理地址。 当一个进程需要某块内存时，如果这块内存地址没有被分配实际的物理内存，那么就会产生缺页异常，这个异常会触发操作系统的缺页异常处理，开始为这段内存分配实际的物理内存。如果当前物理内存够用，分配成功后返回到程序产生缺页异常的那步继续执行。如果物理内存不够用，则考虑内存的换出操作，根据算法，将一部分内存换出以腾出空闲的物理内存分给当前这个产生缺页异常的程序，让程序继续执行。如果既没有空闲物理内存，也没有内存可换出，那就只好返回ENOMEM错误，一直传回用户进程，让用户进程来处理。 好了，关于虚拟内存说的有点多。回到地址越界的问题上，上面说到每一个独立进程都在理论上拥有整个逻辑地址空间，但是并不是所有地址都允许一个用户进程访问。一个进程要想使用内存，必须要先申请分配内存给自己，不管是栈空间还是堆空间等，都不是你说要就有的。当一个程序访问了一段还没有合法分给它的内存地址时，就叫非法地址访问，有的人也叫它指针越界什么的，还有一个更熟悉的报错和它有关，叫段错误（segmentation fault）。而这个SIGSEGV信号就是当产生非法地址访问时，操作系统向产生这个非法访问的进程发送的信号。 这个非法地址访问触发内核向进程发送SIGSEGV信号的设计，应该是符合POSIX标准的。当然，并不是要求所有的系统都要遵守这一标准。这个信号会产生的默认行为就是： 如果在默认这种情况下，程序不捕捉这个信号，那就是这样的效果。或者就让程序捕捉这个信号，给予自定义的处理。 而Windows系统，我没有详细研究过。但是从一份google到的微软关于signal的文档中有这样一段话： 当然，我对windows的了解实在是算少的可怜。不知道这个文档的有效性，我手头也没有可用的windows系统让我去试一下。如果这句话属实，那么windows也应该像其它很多系统一样，在非法地址访问时向进程发送SIGSEGV信号，如果进程不做特殊处理，则被终止运行。 鉴于你只说了“但是Windows下指针越界时，程序会卡死，然后只能手动关掉。”这样一句话，没有任何的实例可供更多分析。所以我这里并不清楚系统有没有给你的程序发送信号，发送了什么信号，你的程序有没有收到这个信号，你的程序有没有捕捉这个信号做了其它处理等等。如果你真的有心弄清楚这个问题，就应该就着这样的思路，看看信号给谁了，收到信号的程序怎么处理的。 不管Windows通过怎么样的机制处理这个问题，它总是要有机质应对段错误这种非常常见的严重错误的。至于你说是“卡死”（死循环？hang住？）还是直接被终结，这和你程序的处理很直接相关。如果你是在一个很复杂的集成环境中，导致你根本不知道在你程序的背后你的开发环境为你添加了怎样的额外处理，那你只有更深入的研究来弄明白从用户进程做非法访问到内核怎么处理怎么返还回用户程序，你的经过重重封装最终编译出来的用户程序怎么处理内核给你的错误反馈，这一整套要有一个有论点有论据的说法。“卡死”两个字的描述其实十分不精确，甚至都不知道是什么样的“卡死”。 关于Windows如何处理非法地址访问，我确实是没有什么研究。Windows内核在设计上确实是和Linux/Unix有很多不同，我没有研究过也不敢妄下定论，欢迎知道详情的朋友不吝补充。一个程序从触发非法地址访问，到Windows如何处理，如何返给用户进程，用户进程如何处理。这一套流程Windows是如何做的呢? 另外我今天搜到了一篇Windows的官方文档，主要面向的是类Unix的程序迁移到Windows时需要注意的事项。其中有介绍Windows下的signal处理的内容。 文中关于信号首先说的一句就是： 然后文中列出了Windows在有限条件下小范围支持的几个信号，接着讲述了如何通过Windows的三个机制将类Unix系统的signal处理迁移到Windows上。这三个分别是： 因为我也是第一次读这个文档，就不把还没有实际使用过的文档里的东西直接拉出来当作自己已经掌握的内容过多复述了。有兴趣的请点开上面的链接自行翻阅。毕竟阅读一手文档的乐趣要远胜于听我在这唠叨，我列在这里就当抛砖引玉了。