x86_64体系结构上Linux 3.0上的进程具有64位虚拟地址空间。
很明显, 0被保证是一个无效的内存地址[见下面的定义]在这个地址空间,因为这是用来表示一个NULL指针。
还有什么其他的64位数字(如果有)保证永远不会成为有效的内存地址,为什么呢?
例如,可以有一个有效的地址? 那么2^64-1呢?
链接到构build系统上使用的libstdc ++版本
双重下划线的含义在一开始
具有向后兼容性的gcc平台调优选项
错误:libtool – 编译MPI程序时
定义 :“ 保证是无效的内存地址 ” 是什么意思?
void deref_and_assign(uint64_t i) { char* p = (char*) i; *p = 42; }
对于这个问题,保证无效的内存引用意味着函数deref_and_assign将总是引发一个SIGSEGV 。
将c ++从Linux移植到windows,'__aligned__'
我可以使用xbuild在Linux上编译一个Visual C ++项目吗?
如何定义“wstring”?
无法编译nn库 – 是不是安装了gcc?
如何确定gcc默认将哪些命令行选项传递给ld?
如果启用了页面转换并且虚拟地址0处的内存不可访问(由于物理内存映射到虚拟地址空间的方式),在x86 / 64上,1 … 4095将不可访问,因为所有这些都是4096地址对应于单个内存页面,它只能作为一个整体可用或不可用。 永远不要映射内存在虚拟地址0是一个好主意。不映射它将有助于捕获许多空指针取消引用。 此处的cpu将在未映射的位置或要求比当前正在执行的代码更高的特权的位置上生成页面错误(aka #PF)。
在64位模式下,cpu可以实现比64个虚拟地址位更少的(48+),而64位地址必须包含全部为零或全部为1的位(值0或1必须是与最重要的实现地址位的值相同,所有这些都可以解释为地址符号扩展)。 这样的地址被称为规范。 如果您尝试使用非规范地址读取或写入内存,则会出现一般性保护错误(AKA #GP)。
所以,根据操作系统(有效地,在其内存布局)和实际的cpu,你可能会提出一系列“无效的”内存地址。 如果您尝试从用户模式应用程序读取/写入内核的内存,您将获得#PF。 如果您尝试读取/写入未映射的内存(例如在地址0到4095),您将获得#PF。 如果您尝试读取/写入非规范地址,则会得到#GP。
这是你要找的东西吗?
你检查一个Linux进程不能用MAP_FIXED mmap开始(void*)0 。
因此,为了实际的目的,你可以放心地假定第一页0 - 0xfff从来没有被mmap -ed(页面的4Kb大小取决于处理器和系统,但是通常是4kb)。 然后你可以假设在第一页里取消引用指针(来自Linux应用程序内部)给出了SIGSEGV
同样地,最后一页以0xffffffffffffffff结尾(即2 ^ 64-1)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。