为什么这两个整数变量和两个双变量(貌似)在内存中共享相同的地址?

时间:2017-08-24 14:00:14

标签: c++ pointers memory

我编写了一个简单的程序,它有一个打印变量地址的方法和存储在该地址中的内容,只是为了帮助我更好地理解指针:

#include <iostream>
using std::cout;
using std::endl;


template<typename Type>
void PrintAddressAndContentsOf(Type Variable);


/* Entry point */
int main()
{
    int IntegerVariable1 = 5;
    int IntegerVariable2 = 6;

    double FloatingVariable1 = 10;
    double FloatingVariable2 = 11;

    PrintAddressAndContentsOf(IntegerVariable1);
    PrintAddressAndContentsOf(IntegerVariable2);
    PrintAddressAndContentsOf(FloatingVariable1);
    PrintAddressAndContentsOf(FloatingVariable2);
}


/* Prints the address and the corresponding contents of a given variable */
template<typename Type>
void PrintAddressAndContentsOf(Type Variable)
{
    Type* Pointer = &Variable;

    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}

当我在Visual Studio上运行它时,我得到以下输出:

Address: 008FFB88
Contents: 5
Address: 008FFB88
Contents: 6
Address: 008FFB84
Contents: 10
Address: 008FFB84
Contents: 11

如您所见,前两个整数似乎具有相同的008FFB88地址;同样,两个浮点指针变量具有相同的地址008FFB84。

我的计划中是否存在缺陷,或者我是否遗漏了一些关键知识以了解这里发生了什么?

3 个答案:

答案 0 :(得分:8)

这里的问题是您打印的是Variable的地址,而不是来自main的变量地址。 Variable的地址与您初始化它的变量的地址无关,并且可以通过多次调用函数来使用相同的地址。

如果我们改为引用,它会给我们一个实际变量的别名而不是像以下那样的副本:

template<typename Type>
void PrintAddressAndContentsOf(Type& Variable)
{
    Type* Pointer = &Variable;

    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}

then we see the addresses are indeed different

Address: 0x7fffc8386ce8
Contents: 5
Address: 0x7fffc8386cec
Contents: 6
Address: 0x7fffc8386cf0
Contents: 10
Address: 0x7fffc8386cf8
Contents: 11

答案 1 :(得分:3)

  

如您所见,前两个整数似乎具有相同的008FFB88地址;同样,两个浮点指针变量具有相同的地址008FFB84。

这些是函数多次调用时函数中变量的地址。它们不是调用函数中变量的地址。如果要检查调用函数中变量的地址,可以使用以下几种方法来完成:

  1. 更改函数以接受指针并将变量的地址传递给函数。

  2. 更改函数以接受引用并将变量传递给函数。

  3. 选项1

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type* variableAddress);
    
    // Usage
    PrintAddressAndContentsOf(&IntegerVariable1);
    

    选项2

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type& variableReference);
    
    // Usage
    PrintAddressAndContentsOf(IntegerVariable1);
    

答案 2 :(得分:2)

您正在打印推入堆栈的变量副本的地址。您的模板按值传递“变量”。

您应该期望(尽管不依赖于)在给定函数内对函数的后续调用,以将参数推送到相同的地址。对不同功能的调用将从同一点开始。

此外,4个字节的差异是因为int是4个字节,double是您平台上的8个字节。反直觉地说,对于你来说,堆栈在地址空间中是“倒置”是很常见的。 “推送”堆栈中的变量实际上会使堆栈顶部向下移动。

尝试以下方法。所有地址都应该不同。

#include <iostream>
using std::cout;
using std::endl;


template<typename Type>
void PrintAddressAndContentsOf(Type* Pointer);


/* Entry point */
int main()
{
    int IntegerVariable1 = 5;
    int IntegerVariable2 = 6;

    double FloatingVariable1 = 10;
    double FloatingVariable2 = 11;

    PrintAddressAndContentsOf(&IntegerVariable1);
    PrintAddressAndContentsOf(&IntegerVariable2);
    PrintAddressAndContentsOf(&FloatingVariable1);
    PrintAddressAndContentsOf(&FloatingVariable2);
}


/* Prints the address and the corresponding contents of a given variable */
template<typename Type>
void PrintAddressAndContentsOf(Type* Pointer)
{
    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}