-2

intptr_t我想知道在使用以下 c/c++ 函数(或更多)时是否保证内存地址为正整数,包括零?也许你可以帮我这样列出他们的结果,或者如果没有,请给我一个总结,

功能 操作系统 建筑学 空间 结果范围
malloc Linux AMD64 用户 总是积极的?
malloc 视窗 AMD64 用户 总是积极的?
堆分配 视窗 x64 用户 总是积极的?
新运营商 视窗 x64 用户 总是积极的?
地图

参考

4

4 回答 4

2

您在中途编辑了您的问题,从而大大改变了它的解释。我将回答两个版本。

我想知道是否可以保证内存地址是正整数

至少在 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. 如果您希望获得这样的保证,如果您正在考虑编写一个使用它的程序,我强烈建议您重新考虑,如果可能的话。

(多年来,出于各种“聪明”原因,各种“聪明”程序都试图篡夺指针变量的一位或多位,将其用作标志以达到自己的目的,因为他们知道这些位对于实际指针来说是微不足道的那天的地址。虽然这些程序可能获得了短期的性能提升,但根据我的经验,这些技巧最终总是会毁掉。我会像避免瘟疫一样避免它们。)

于 2021-07-29T13:40:44.307 回答
0

我想知道是否可以保证内存地址是正整数

任何硬件工程师都会将内存地址视为正数。

但是在 C 编程中它没有任何意义。在编程中,我们有指针,它们不是整数。它们是一些可打印的位模式(实现定义)。打印指针可以给你

FFFFFFFF00112233

你可以随心所欲地看待它是积极的还是消极的,但这没有意义。根据 C 标准,它们不是整数,因此既不是正数也不是负数。

您可以将指针转换为intptr_tuintprt_t。这些分别是有符号和无符号的。所以你能得到的范围取决于你想要什么。

于 2021-07-29T14:11:25.973 回答
0

在 C(和 C++)中,整数和指针类型(对象的内存地址,通用形式:)之间有明显的区别void*

这两种类型都是兼容的类型并且属于同一组,即标量类型。

该类型ptrdiff_t是两个指针相减时返回的有符号整数类型。自 C99/C++11 以来,随着固定宽度整数类型的引入,我们也有了能够保存指针的类型intptr_t和, 整数类型。uintptr_t

因此,总而言之,如果您在谈论地址(指针),那么您不是在谈论整数类型。由于两者都是标量类型,因此它们彼此兼容,因此(在某些情况下)可以互换。但永远不相等。因此,(我认为)您的问题毫无意义。

参考

于 2021-07-29T13:42:20.457 回答
-1

当您将指针转换为intprt_tthen 时,如果转换为的指针的值uintptr_t大于INTPTR_MAX然后转换为的值intptr_t将是负数(假设二进制补码有符号整数格式)。

于 2021-07-29T13:44:04.453 回答