【问题标题】:Pointers and addresses in C++C++中的指针和地址
【发布时间】:2021-12-24 00:57:08
【问题描述】:

我有点搞乱指针。请查看以下结果(地址)。

第一个代码:

#include <iostream>

int main(){
    int a = 5;
    void* pointer = &a;
    std::cout << a << std::endl << &a << std::endl;
    std::cout << pointer << std::endl ;
    std::cin.get();
}  

结果:

第二个代码:

#include <iostream>

int main(){
    int a = 5;
    void* pointer = &a;
    std::cout << a << std::endl << &a << std::endl;
    std::cout << &pointer << std::endl ;
    std::cin.get();
}  

结果:

为什么两个代码之间变量a的地址会发生变化?

【问题讨论】:

  • 请澄清:您是在询问 0x7bfe14 和 0x7bfe1c 之间的区别吗?还是别的什么?
  • @463035818_is_not_a_number 是的,为什么地址变了?
  • 变量a的地址因不同而不同。变量a 包含一个int 值,并且该值设置为5。这对于两段代码都是相同的。不要纠结于变量的存储位置;该信息有时在程序内部很有用,但不要求a 在两个不同的程序中位于同一位置,甚至在多次运行时也不要求位于同一程序中。跨度>
  • @KenZa 不,该变量不需要存在于第一个代码中,它已被优化掉。你对它所做的只是存储一个固定值,然后再读回来,所以甚至不需要这个变量,编译器也不会使用它。编译器可以处理它,就好像您在第二个输出行中写了&amp;a 而不是pointer,节省了一些空间和执行时间。
  • @CherryDT 哦,所以当你说“这些变量都不必真正存在”时,c 包含在此声明中

标签: c++ pointers memory-address


【解决方案1】:

这很简单。 int a 和 void* pointer 是两个不同的变量,或者我最好说 内存位置 在堆栈上。 a 在它的位置保存一个类似 5 的值。 pointer 保存a 的内存位置的地址。 pointer 本身存储在不同的位置,当您编写 std::cout &lt;&lt; &amp;pointer &lt;&lt; std::endl; 时,它将打印 pointer 变量的地址,而不是 a 的地址的内容。

作为一个简化的例子:

将0x4视为pointer本身的地址,其中的值为0xC。该值指向a 的位置。为了读取a(即5)的值,您首先必须转到0x4 以读取其内容。它的内容是0xC,现在你已经成功发现a的位置是0xC。然后你必须去 0xC 并且在那个地址,你会找到值 5。

你看 -> 0x4( content == 0xC ) -> 0xC( content == 5 ) -> 完成!

【讨论】:

    【解决方案2】:

    在第一个代码poiner中存储了变量a的地址,并通过命令。

    std::cout<<pointer<<std::endl;
    

    您打印a 的地址。而已。 在第二个代码中pointer也存储了变量a的地址,但&amp;pointer是变量pointer的地址。试试下面的

    #include <iostream>
    int main(){
        int a = 5;
        void* pointer = &a;
        void** pointer_to_pointer = &pointer;
        std::cout << a << std::endl << &a << std::endl << pointer << std::endl;
        std::cout << &pointer << std::endl << pointer_to_pointer;
        std::cin.get();
    }  
    

    我的输出是

    5
    0x7aba1bd92e94
    0x7aba1bd92e94
    0x7aba1bd92e98
    0x7aba1bd92e98
    

    【讨论】:

    • 是的,我知道的是,这不是我的问题,我的问题是为什么a 的地址会在两个程序之间发生变化,因为我所做的只是更改不应影响内存的输出
    【解决方案3】:

    在第一种情况下,您永远不会获取pointer 的地址,因此pointer 可以存储在寄存器中,甚至根本不存储。 (现代编译器非常聪明,现代机器有很多寄存器。)

    例如,gcc 11 将值保存在寄存器中而不进行优化,而-O2 它只是直接插入a 的地址。 (大会here,好奇的人。)

    在第二种情况下,您确实获取了pointer的地址,因此它必须存储在内存中的某个位置。
    这意味着a 可能会存储在不同的位置以便为其腾出空间。

    此外,一些平台会随机存储位置以降低程序的可破解性,因此假设事物在不同的“运行”中具有相同的地址通常不是一个好主意。

    【讨论】:

    • 在第一种情况下,指针可能没有地址吗?但我认为pointer 是一个变量,所以它存储在某个地方,因为它是一个变量,并且它包含一个值,它是a 的地址,所以pointer 需要存储在某个地方,因为它包含一个值跨度>
    • 它可能在寄存器中,也可能根本不存在,因为它的值可以在编译期间静态计算。
    • @KenZa:在 C++ 中,如果和何时需要一个地址是很常见的。这是相当自动的。但是,有些东西不会自动获取地址,例如 2+2 之类的临时地址。如果你想要一个地址,你需要自己将结果存储在某个地方。
    • @KenZa 是的,pointer 是一个变量,但编译器只有在需要时才会将其值存储在某个地方,如果不需要,具有自动存储功能的对象将尽可能多地存储在寄存器中因为它比访问内存要快得多。
    • @molbdnilo 所以你是说如果编译器不需要“输出”指针而只能访问它,那么它将存储在寄存器而不是内存中?跨度>
    猜你喜欢
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 2013-11-05
    • 1970-01-01
    相关资源
    最近更新 更多