代码改变世界

空指针赋值分区

  Clingingboy  阅读(851)  评论(0编辑  收藏  举报

 

转:http://www.cnblogs.com/anzhihun/archive/2009/08/08/1349032.html

  1. 为什么通过空指针读写的时候就会出现异常?
  2. 除了NULL表示空指针,是否还有其他的值也是空指针?
  3. 如果还有其他的值,你们这些表示空指针的值都是什么?为什么?

首先解答第一个问题,在windows核心编程第四版的windows的内存结构一章中,表13-1有提到NULL指针分配的分区。其范围是从0x00000000到0x0000FFFF。这段空间是空闲的,对于空闲的空间而言,没有相应的物理存储器与之相对应,所以对这段空间来说,任何读写操作都是会引起异常的。

有了上面的解答后,第二个问题就很容易解答了。NULL的定义出现以下几个地方:

stdio.h文件中

#ifndef NULL
#ifdef  __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

ios.h文件中

#ifndef NULL
#define NULL    0
#endif

windef.h文件中

#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

可见,NULL的值,基本上是用0来表示的,是不是只能用0呢?在windows xp sp2的系统平台下,如果执行下面代码也是会发生异常的:

int * pAddr = (int *)0x0000ffff;

*pAddr = 1;

而下面的代码是不会出问题的:

int * pAddr = (int *)0x00010000;

*pAddr = 1;

为什么呢?在windows xp sp2下发现0x00000000到0x0000FFFF是空闲区间,而0x00010000所处的是进程的私有区间。我想第二个问题应该已经解决了,我想,空指针是程序无论在何时都没有物理存储器与之对应的地址。为了保障“无论何时”这个条件,需要人为划分一个空指针的区域,固有上面NULL指针分区。

在第二个问题的基础上,要解答NULL指针的范围,那就相对来说容易了,对于在32位x86计算机上运行的windows xp sp2来说,就是从0x00000000到0x0000ffff。为什么分配如此大的空间?而在定义NULL的时候,只使用了 0x00000000这么一个值,这不是浪费吗?我想,这是操作系统地址空间的分配粒度相关的,windows xp sp2的分配粒度是64KB,为了达到对齐,空间地址需要从0x00010000开始分配,故空指针的区间范围有那么大。

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2011-03-20 Win32 控件篇(4)
2011-03-20 Win32 控件篇(3)
2011-03-20 Win32 控件篇(2)
2011-03-20 Win32 控件篇(1)
2011-03-20 Win32 窗口篇(4)
2011-03-20 Win32 窗口篇(3)
2011-03-20 Win32 窗口篇(2)
点击右上角即可分享
微信分享提示