将 int 转换为 int* 然后再转换回 int

发布于 2024-10-17 10:07:13 字数 694 浏览 2 评论 0原文

我在这里遗漏了一些明显的东西,但考虑以下,

int k = 10;
int *p = &k;
int i = (int)p;

上面的产生,

warning: cast from pointer to integer of different size

以及以下的

int k = 10;
int *p = &k;
int i = p;

原因,

warning: initialization makes integer from pointer without a cast

一些谷歌搜索引导我,

将指针转换为整数

建议使用 uintptr_t,

int k = 10;
int *p = &k;
int i = (uintptr_t)p;

上面的工作没有错误没有警告。所以我的问题是 k 是一个 int 而 p 是一个指向 k 的 int 指针,为什么我会收到取消引用 p 的错误?

I am missing something obvious here but consider the following,

int k = 10;
int *p = &k;
int i = (int)p;

above produces,

warning: cast from pointer to integer of different size

and following,

int k = 10;
int *p = &k;
int i = p;

causes,

warning: initialization makes integer from pointer without a cast

a bit of googling lead me to,

Converting a pointer into an integer

which advices using uintptr_t,

int k = 10;
int *p = &k;
int i = (uintptr_t)p;

above works no errors no warnings. So my question is k is an int and p is an int pointer pointing to k why do i get an error dereference p?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浅浅 2024-10-24 10:07:13
int k = 10;
int *p = &k;
int i = *p;

请注意最后一行 p 之前的 *。取消引用指针以获取它指向的 int。

编辑:我不太熟悉 uintptr_t,但我运行了代码 int i = (uintptr_t)p;
存储到 i 中的结果是 k 的内存地址,而不是 10。强制转换告诉编译器您确实想要将该地址转换为整数(因此不会有警告;因为您坚持让编译器知道您知道什么)你正在做)但不取消引用指针。

int k = 10;
int *p = &k;
int i = *p;

Note the * before p on the last line. Dereference the pointer to get the int it points to.

EDIT: I'm not very familar with uintptr_t, but I ran the code int i = (uintptr_t)p;
The result that is stored into i is the memory address of k, not 10. The cast tells the compiler that you really want to turn the address into an integer (so there's no warning; because you are insisting to the compiler that you know what you are doing) but does not dereference the pointer.

澜川若宁 2024-10-24 10:07:13

您会收到错误,因为您实际上并未取消引用 p,您只是从 int* 强制转换它(强制更改其类型)。要取消引用,您需要使用 * 运算符,如下所示:

int i = *p;

You get an error because you didn't actually dereference p, you just casted it (forcefully changed its type) from int*. To dereference, you need to use the * operator, like so:

int i = *p;
诺曦 2024-10-24 10:07:13

您没有取消对指针的引用,因此您将指针的地址分配给 int。

int i = *p;

是您最可能想要的。

You aren't dereferencing the pointer, so you are assigning the address of the pointer to an int.

int i = *p;

Is what you most likely wanted.

晚风撩人 2024-10-24 10:07:13

您正在使用 int 到指针的转换,这并不能保证两者甚至不再使用相同的内存量。实际上,当人们这样做时,它并不能保证使用相同的尺寸,但对于大多数平台来说,它只是碰巧工作。

由于您在后一个示例中显式进行了强制转换,因此编译器认为这不是一个错误(或者您为什么要输入它?)。这就是编译器输出差异的原因。

请注意,如果您不想将 k 的内存地址存储到 i 中,那么将 K 的值放入 i 中的正确方法是

int i = *p;

You're playing with int to pointer casting, and that has no guarantee that the two even use the same amount of memory anymore. Actually it didn't have a guarantee of using the same size back when people did it, but for most platforms it just happened to work anyway.

Since you explicitly cast in the latter example, the compiler assumes it wasn't a mistake (or why would you have typed it out?). That's the reason for the difference in compiler output.

Note that if you didn't want to store the memory address of k into i, then the proper way to get K's value into i would be

int i = *p;
怀中猫帐中妖 2024-10-24 10:07:13

您将 i 设置为等于 k 的地址(这是 p 所保存的内容)。并且地址值是无符号类型。因此,当从指针进行转换时,它会抱怨,因为您正在将转换和无符号值转换为有符号值。

此外,根据平台不同,指针的大小也不同,因此 32 位指针小于 64 位指针。因此,如果指针是 8 字节无符号指针,则需要将其转换为 4 字节有符号指针。

You are setting i equal to the address of k (which is what p holds). And the address value is an unsigned type. So when casting from the pointer, it complains because you are taking casting and unsigned value to signed.

Also pointers are different sized types based on the platform, so 32 bit pointers are smaller than 64. So if the pointer is a 8 byte unsigned, you are casting it down to a 4 byte signed.

流云如水 2024-10-24 10:07:13

这就是它应该看起来的样子

int k = 10;
int *p = &k;
int i = *p;

这里是我的想法

k = 10

p = 某个地址

&k = 某个地址

*p = 10

this is how it should look

int k = 10;
int *p = &k;
int i = *p;

here is how I think of it

k = 10

p = some address

&k = some address

*p = 10

清秋悲枫 2024-10-24 10:07:13

uintptr_t 并不是一种中间转换为 int 的类型,而是这样使用的。如果它是在系统上定义的(并且您的系统似乎有它),那么它是无符号整数类型,当您使用指针值加载它时,您不会丢失信息。因此,如果必须,请完全使用 uintprt_t 而不是 int。但这应该是很少见的情况,而且在大多数情况下,我敢打赌,这只是糟糕设计的标志。

无论如何,int 从一开始就是一个坏主意。如果有的话,指针值只是虚拟内存空间中的一个位置,将其视为有符号值对我来说根本没有意义。

uintptr_t is not meant as a type to do an intermediate cast to int but used as such. If it is defined on a system (and yours seems to have it) it is the unsigned integer type where you don't loose information when you load it with a pointer value. So if you must, use uintprt_t fully instead of int. But this should be rare occasions, and in most cases I would bet, this is just a sign of bad design.

In any case int is a bad idea from the start. If anything, a pointer value is just an position in a virtual memory space and seeing it as a signed value makes no sense to me at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文