简体   繁体   中英

Why do these two integer variables and two double variables (seemingly) share the same address in memory?

I wrote a simple program that has a method for printing the address of a variable and the contents stored in that address, just to help me understand pointers a little bit better:

#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;
}

When I ran this on Visual Studio, I got the following output:

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

As you can see, the first two integers seem to have the same address of 008FFB88; likewise, the two floating pointer variables have the same address of 008FFB84.

Is there a flaw in my program, or am I missing some key knowledge for understanding what's going on here?

The issue here is you are printing the address of Variable , not the address of the variables from main. The address of Variable is independent of the address of the variable you initialize it from and can be the same address through multiple calls to the function.

If we take a reference instead, which give us an alias to the actual variable and not a copy like:

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

As you can see, the first two integers seem to have the same address of 008FFB88; likewise, the two floating pointer variables have the same address of 008FFB84.

Those are the addresses of the variable in the function in multiple invocations of the function. They are not the addresses of the variables in the calling function. If you want to examine the addresses of the variables in the calling function, you can do that using couple of methods:

  1. change the function to accept a pointer and pass the addresses of the variables to the function.

  2. change the function to accept a reference and pass the variables just as you have to the function.


Option 1

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

// Usage
PrintAddressAndContentsOf(&IntegerVariable1);

Option 2

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

// Usage
PrintAddressAndContentsOf(IntegerVariable1);

You're printing the address of the copy of the variables that is pushed onto the stack. Your template passes `Variable' by value.

You should expect (though in no way rely on) subsequent calls to a function from within a given function to push the arguments to the same addresses. Calls to different functions will start from the same point.

Furthermore the difference of 4 bytes is because int is 4 bytes and double is 8 bytes on your platform. Counter-intuitively it is common and again true for you that the stack is 'upside down' in address space. 'pushing' variables on the stack actually moves the top of the stack down.

Try the following. All the addresses should be different.

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM