【问题标题】:Pointer with same memory address with different value具有相同内存地址但值不同的指针
【发布时间】:2017-07-30 22:21:48
【问题描述】:

我将内存地址从 double 转换为 integer 。 即使它们指向相同的地址,为什么值不同?

#include<iostream>
using namespace std;

int main()
{
    double d = 2.5;
    auto p = (int*)&d;
    auto q = &d;
    cout<<p<<endl; // prints memory address 0x7fff5fbff660
    cout<<q<<endl; // print memory address  0x7fff5fbff660
    cout<<*p<<endl; //prints 0
    cout<<*q<<endl; // prints 2.5
    return 0;

}

但是为什么值不一样

0x7fff5fbff660
0x7fff5fbff660
0
2.5
Program ended with exit code: 0

【问题讨论】:

    标签: c++


    【解决方案1】:

    假设你在一张纸上写了“11”。如果是十进制数字,那就是十一。如果每个值都有一个标记,则为两个。如果它是二进制的,那就是三个。你如何解释存储的信息会影响你理解它存储的价值。

    【讨论】:

      【解决方案2】:
      double d = 2.5;
      auto p = (int*)&d;
      auto q = &d;
      

      p 和 q 被创建指向相同的内存位置。内存持有双倍(通常为 8 个字节)

      当你创建时

      auto p = (int*)&d;
      

      您是在告诉编译器 (reintepret_cast&lt; int*&gt; ( &amp;d)) d 中的值是一个整数。

      所以指针的值相同,但类型不同。

      当你打印出来

      cout<<*q<<endl; // prints 2.5
      

      您正在显示正确的值 - 因为它通过它进出。

      当你打印出来时

      cout<<*p<<endl; //prints 0
      

      您正在查看 8 字节内存中的 4 个(通常)字节,并将它们解释为整数。

      这些恰好是 0x00、0x00、0x00、0x00

      【讨论】:

        【解决方案3】:

        这是因为您违反了strict aliasing rule,导致您出现未定义的行为。您不能通过类型 B 的指针访问类型 A 并假装它有效。


        TL;DR:

        如果你有一个int* 指向一些包含int 的内存,然后 您将float* 指向该内存并将其用作float 您打破了 规则。如果您的代码不尊重这一点,那么编译器的 优化器很可能会破坏您的代码。

        【讨论】:

          【解决方案4】:

          内存地址相同,都指向内存中的双精度浮点数。但是,您已要求编译器将一个视为整数,将另一个视为双精度数。 (指针可能只是一个内存地址,但在编译时,编译器也有关于类型的信息。)碰巧这个特定双精度数的内存表示在被视为 0 时看起来像 0一个整数。

          【讨论】:

            【解决方案5】:

            因为您自己已将它们转换为不同的类型。

            【讨论】:

            • 是的,我做到了:)。内存地址是一样的
            • 查看上面@mksteve的详细回答。
            【解决方案6】:

            当您执行auto p = (int*)&amp;d; 时,您要求编译器将双精度值存储在为整数分配的内存区域中。整数和双精度在计算机内存中以不同的格式表示。 double 使用浮点 representation 存储在内存中,而 int 则不是。这是未定义行为的典型示例。

            【讨论】:

            • 如果您能解释投票背后的理由会很好。
            • “要求编译器将双精度值存储在为整数分配的内存区域中” - 错误。这不存储双精度。该语句不存储任何内容。双子已经在那里了。演员表是一个将双精度值解释为 int 的请求,这可能会导致其他答案中描述的问题。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-08
            • 1970-01-01
            • 2018-06-04
            • 1970-01-01
            • 2019-04-07
            • 1970-01-01
            相关资源
            最近更新 更多