![]() |
1
4
所有现代操作系统都巧妙地使用虚拟内存管理硬件实现了一个空指针取消引用检查,并且没有执行开销。第0个4 KB页(或在本例中为0-15页(总计64 KB))已设置,因此地址0(或0x00000FFF或0x0000fff)处的任何数据读写或指令执行都会立即导致访问冲突异常。 让我换一种说法。捕获对0的空指针解引用,但允许对(例如)地址1的数据引用,代价将非常昂贵——因为您不能使用页面粒度的虚拟机硬件,而是需要在许多指针解引用之前执行空指针比较和分支序列。通过使第一页或前几页不可访问,可以在VM硬件中“免费”完成此检查。缺点是你不能用这些首页来做其他事情。 (理论上,可以使用一个充分优化的编译器来确定哪些指针解引用不可能是空指针解引用,但在出现这样聪明的编译器之前,必须使用未映射的0页技巧。) 那么,为什么Windows(post Win98)的空指针分配分区是64kb,而不是必需的最小4kb?Wyzard的答案也很适合捕捉空指针数组索引错误。 *最新更新:回复:为什么是64 KB?--我问了一个应该了解Windows核心团队的人,他们说这可能是一个64kb区域,因为Windows将某些内存管理结构保持在64kb的分配粒度。为什么?我不知道,但也许陈雷蒙有答案: http://blogs.msdn.com/b/oldnewthing/archive/2003/10/03/55239.aspx . 真 的。* |
![]() |
2
3
在C或C++语言中,NULL总是等于0,但是作为源代码中的指针值的0并不一定对应于编译后的二进制中的所有零位。但是,在Windows上,我相信空指针实际上都是零位。
保留的空间可能有助于捕捉
|
![]() |
3
0
这个范围是必要的,以便于检测由于取消引用空指针和接近空指针而导致的错误。例如:
注意:在上面的示例中从来没有取消对空指针的引用。但自从
|
![]() |
4
0
范围是必需的,因为当指向结构或类元素的指针被取消引用时,访问的实际内存将是指针,加上结构中成员的偏移量。
在int=32位编译器上,“b”成员将在结构中占4个字节,因此Bar->b将尝试访问地址0x00000004。 |
![]() |
CalculusLover · 在本例中,fork()是如何工作的? 2 年前 |
![]() |
jjmerelo · 使用Proc::Async从绑定管道读取 6 年前 |
![]() |
jatinBatra · 编译后生成的二进制文件会发生什么情况[关闭] 6 年前 |
![]() |
Jacobo · 从Java调用具有输入和输出重定向的C可执行文件 6 年前 |
![]() |
Ran · 每当我尝试执行命令行提示符时,Unity就会阻塞 6 年前 |
![]() |
Hatshepsut · 使用命令行参数使用region调用子流程 6 年前 |