哪些内存地址永远无法指向有效对象,可作为指针标记值在主流桌面系统使用
各系统可用的固定无效虚拟地址范围
以下是三个系统用户态下永远不会被分配给有效对象的地址段,你可以直接取其中的地址作为标记值使用:
Linux
- 32位系统:内核占用最高1GB地址空间,
0xC0000000 ~ 0xFFFFFFFF范围全为无效用户态指针,你示例中用到的0xffff0000段完全符合要求。 - 64位系统:虚拟地址仅使用低48位,高16位全为1的地址段
0xFFFF000000000000 ~ 0xFFFFFFFFFFFFFFFF全为内核预留,不会分配给用户态,可自由选取作为标记。
Windows
- 32位系统:默认2GB用户态空间,
0x80000000 ~ 0xFFFFFFFF为内核预留地址,不会分配给用户态对象。 - 64位系统:同样仅使用低48位虚拟地址,
0xFFFF000000000000 ~ 0xFFFFFFFFFFFFFFFF范围完全无效,此外最低64KB地址段0x00000000 ~ 0x0000FFFF也默认预留,访问直接报错,也可作为标记使用。
macOS
- 64位x86/arm64架构:高16位全为1的地址段
0xFFFF000000000000 ~ 0xFFFFFFFFFFFFFFFF为内核预留,永远不会分配给用户态应用。 - 已淘汰的32位版本:
0x80000000 ~ 0xFFFFFFFF为内核预留地址,可安全使用。
使用建议
- 定义标记时建议直接转型为对应指针类型,避免编译器报整数转指针的警告,示例写法:
#define SIZE_TOO_SMALL ((char*)0xffff0001) - 优先选用高地址预留段作为标记,比低地址段兼容性更好,不会遇到null页特殊映射的异常场景。
- 64位环境下建议直接用宏定义标记值,避免枚举类型宽度不足的问题。
内容的提问来源于stack exchange,提问作者rtpax
相关产品推荐
相关产品推荐

