在Windows中,堆栈的实现方式如下:指定的页面紧随提交的堆栈页面。这是保护标志是守卫。因此,当adad引用受保护页面上的地址时,内存故障会增加,这会使内存管理器将保护页面提交到堆栈并清除页面的保护标志,然后保留一个新的页面作为守护进程。在堆栈上分配更多页面大小的缓冲区会损坏内存?
当我分配一个大小超过一页(4KB)的缓冲区时,但是,没有发生预期的错误。为什么?
在Windows中,堆栈的实现方式如下:指定的页面紧随提交的堆栈页面。这是保护标志是守卫。因此,当adad引用受保护页面上的地址时,内存故障会增加,这会使内存管理器将保护页面提交到堆栈并清除页面的保护标志,然后保留一个新的页面作为守护进程。在堆栈上分配更多页面大小的缓冲区会损坏内存?
当我分配一个大小超过一页(4KB)的缓冲区时,但是,没有发生预期的错误。为什么?
优秀的问题(+1)。
有一个窍门,很少有人知道它(除了司机作家)。
当您在堆栈上分配大缓冲区时 - 编译器会自动添加所谓的堆栈探测器。这是一个额外的代码(通常在CRT中实现),它以所需的顺序逐页探测分配的区域。
编辑:
功能是_chkstk
。
故障没有到达您的程序 - 它由操作系统处理。类似的事情发生在程序试图读取恰巧写入交换文件的内存时 - 发生陷阱并且操作系统断开页面并且程序继续。
几乎正确。当您按顺序访问堆栈并跨越下一个页面边界时,会发生这种情况。但是在上述场景中,当您在堆栈中分配大型变量时,需要额外的技巧。 – valdo 2010-11-08 12:41:41
我在哪里可以看到该代码? – sharptooth 2010-11-08 12:41:24
记录在这里:http://msdn.microsoft.com/en-us/library/ms648426%28VS.85%29.aspx – valdo 2010-11-08 12:44:17
另请参见chkstk.asm在CRT源代码(用于MSVC) – valdo 2010-11-08 12:45:27