intptr_t
我想知道在使用以下 c/c++ 函数(或更多)时是否保证内存地址为正整数,包括零?也许你可以帮我这样列出他们的结果,或者如果没有,请给我一个总结,
功能 | 操作系统 | 建筑学 | 空间 | 结果范围 |
---|---|---|---|---|
malloc | Linux | AMD64 | 用户 | 总是积极的? |
malloc | 视窗 | AMD64 | 用户 | 总是积极的? |
堆分配 | 视窗 | x64 | 用户 | 总是积极的? |
新运营商 | 视窗 | x64 | 用户 | 总是积极的? |
地图 |
参考
您在中途编辑了您的问题,从而大大改变了它的解释。我将回答两个版本。
我想知道是否可以保证内存地址是正整数
至少在 C 和 C++ 中,内存地址就是内存地址——它不一定是整数。在这些语言中,内存地址(指针)和整数之间的转换是有问题的,它们需要显式强制转换,而且它们并不总是能保证工作。但是,如果我们确实将内存地址视为整数,我们总是将它们视为无符号整数,这意味着它们在几乎任何平台上都不能为负数。
我想知道是否有保证内存地址是一个正整数,包括零,在
intptr_t
啊哈。非常不同的问题。 intptr_t
是有符号类型,所以现在我们想知道的是,基本上,地址空间的“上半部分”中是否有任何地址,这意味着它们具有其高阶(最高有效)位集,这意味着它们'如果我们将它们视为有符号类型,则重新解释为负数?
当我第一次学习 C 时,在 16 位 PDP-11 上,堆栈位于地址空间的顶部,从 address0xffff
或 -1 开始,所以是的,我看到了很多“负”地址,通常是任何堆栈地址. (在那些日子里我们没有intptr_t
,但如果我们将它们视为有符号整数,我们确实有看起来为负的地址。)
当 Unix 第一次被移植到 32 位 VAX 和 AFAIK 时,大多数/所有 32 位版本的 Unix 和 Linux,用户内存被限制在虚拟内存地址空间的“下半部分”,而操作系统本身映射到上半部分。因此,在这些平台上,事实证明用户地址总是看起来是积极的,我猜这就是你要问的。
我不知道 Windows 是如何做事的,也不知道在现代 64 位操作系统上通常是如何布置的(当您的操作系统设置为支持 32 位或 64 位时更是如此位程序)。
所以我真的不能帮你填表。当然,不能保证用户地址在转换为intptr_t
. 如果您希望获得这样的保证,如果您正在考虑编写一个使用它的程序,我强烈建议您重新考虑,如果可能的话。
(多年来,出于各种“聪明”原因,各种“聪明”程序都试图篡夺指针变量的一位或多位,将其用作标志以达到自己的目的,因为他们知道这些位对于实际指针来说是微不足道的那天的地址。虽然这些程序可能获得了短期的性能提升,但根据我的经验,这些技巧最终总是会毁掉。我会像避免瘟疫一样避免它们。)
我想知道是否可以保证内存地址是正整数
任何硬件工程师都会将内存地址视为正数。
但是在 C 编程中它没有任何意义。在编程中,我们有指针,它们不是整数。它们是一些可打印的位模式(实现定义)。打印指针可以给你
FFFFFFFF00112233
你可以随心所欲地看待它是积极的还是消极的,但这没有意义。根据 C 标准,它们不是整数,因此既不是正数也不是负数。
您可以将指针转换为intptr_t
和uintprt_t
。这些分别是有符号和无符号的。所以你能得到的范围取决于你想要什么。
在 C(和 C++)中,整数和指针类型(对象的内存地址,通用形式:)之间有明显的区别void*
。
这两种类型都是兼容的类型并且属于同一组,即标量类型。
该类型ptrdiff_t
是两个指针相减时返回的有符号整数类型。自 C99/C++11 以来,随着固定宽度整数类型的引入,我们也有了能够保存指针的类型intptr_t
和, 整数类型。uintptr_t
因此,总而言之,如果您在谈论地址(指针),那么您不是在谈论整数类型。由于两者都是标量类型,因此它们彼此兼容,因此(在某些情况下)可以互换。但永远不相等。因此,(我认为)您的问题毫无意义。
参考:
当您将指针转换为intprt_t
then 时,如果转换为的指针的值uintptr_t
大于INTPTR_MAX
然后转换为的值intptr_t
将是负数(假设二进制补码有符号整数格式)。