Is there any way to find the address of a reference?

C++Reference

C++ Problem Overview


Is there any way to find the address of a reference?

Making it more specific: The address of the variable itself and not the address of the variable it is initialized with.

C++ Solutions


Solution 1 - C++

References don't have their own addresses. Although references may be implemented as pointers, there is no need or guarantee of this.

The C++ FAQ says it best:

> Unlike a pointer, once a reference is > bound to an object, it can not be > "reseated" to another object. The > reference itself isn't an object (it > has no identity; taking the address of > a reference gives you the address of > the referent; remember: the reference > is its referent).

Please also see my answer here for a comprehensive list of how references differ from pointers.

The reference is its referent

Solution 2 - C++

NO. There is no way to get the address of a reference.
That is because a reference is not an object, it is an alias (this means it is another name for an object).

int  x = 5;
int& y = x;

std::cout << &x << " : " << &y << "\n";

This will print out the same address.
This is because 'y' is just another name (an alias) for the object 'x'.

Solution 3 - C++

The ISO standard says it best:

> There shall be no references to references, no arrays of references, and no pointers to references.

I don't like the logic a lot of people are using here, that you can't do it because the reference isn't "guaranteed to be just a pointer somewhere anyway." Just as int x may be only a processor register with no address, but magically becomes a memory location when & x is used, it still may be possible for the compiler to allow what you want.

In the past, many compilers did allow exactly what you're asking for, eg

int x, y;
int &r = x;
&r = &y; // use address as an lvalue; assign a new referent

I just checked and GCC will compile it, but with a strongly worded warning, and the resulting program is broken.

Solution 4 - C++

No.

As Bjarne Stroustrup says in TC++PL, a reference can be thought of as just another name for an existing entity (object or function). While this is not always the most precise description of the underlying low-level mechanism that implements references, it is a very good description of the concept the references are intended to implement at the language level. Not surprisingly, the language provides no means to obtain the address of reference itself.

At language level reference is not guaranteed to occupy a place in storage, and therefore in general case it has no address.

Solution 5 - C++

From another instance of this same question: $8.3.2/3 - "It is unspecified whether or not a reference requires storage (3.7).".

So the C++ standard allows the compiler/runtime implementor to choose whether or not a reference lives in a separate memory location. However note that if it does live in a separate memory location, you can't find its address in a standard-compliant manner. So don't do it.

If you take an address of a reference, by definition in the C++ standard, you will get the address of what it refers to, rather than the address of the reference, if in fact that reference even exists as a separate entity in the runtime environment or not.

Solution 6 - C++

Just use the '&' operator. e.g :

int x = 3;
int &y = x;
cout<<&y<<endl;

This will return the address of x since y is nothing more than the address of x.

Solution 7 - C++

Not reliably, as references don't have to have a unique location in addressable memory.

Solution 8 - C++

Not by itself. If you want its "address", shove it in a struct or class. Even then that isn't necessarily guaranteed to get you within the vicinity of what you probably want to do which is using a pointer. If you want proof, the sizeof of a reference is equal to the referent type. Try it with char & and see.

Solution 9 - C++

It is possible, but not strictly using C++. Since the reference is passed as a parameter of a function, its value will be stored on the stack or in a register. This is hardware architecture dependent. Access to these values will require inline assembly. Consult the reference manual for the processor you are using to determine stack behavior and register addresses. Corrupting the stack or registers can very easily cause BSOD, data loss, or even permanent damage to your system. Proceed with extreme caution.

Solution 10 - C++

If you implement a reference as a member of a struct, you then can get its address:

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){
  }
};

The reference indeed a pointer (in my case using Xcode compiler) and you can update it's value to re-assign the reference to a new variable. To do so we need to find out the address of the reference and trick it value to address of other variable

Now the address of the reference TestRef.r is the address of TestRef object.Because r is the first member of TestRef.

You can re-assign the reference by updating the value store in the memory of TestRef.r.

This code below shows that you can get address of reference and you and re-assign a reference to a difference variable. Note: my OS is X64 OS (I use Xcode MacBook Pro 2015, MacOs 10.15.1).

#include <iostream>
using namespace std;

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){}
};

int main(int argc, const char * argv[]) {
  int i = 10;
  int j = 11;
  TestRef r(i); // r.r is reference to i
  
  cout << r.r << " " << i << " " << j << endl; // Output: 10 10 11
  
  int64_t* p = (int64_t*)&r; // int32_t in 32 bit OS; 
  // Note: 
  // p is the address of TestRef r and also the address of the reference r.r
  // *p is the address of i variable
  //
  // Difficult to understand? r.r indeed a pointer to i variable 
  // *p will return the address inside the memory of r.r
  // that is the address of i variable
  // this statement is true: *p == &i  
  // ------>
  // now we change the value of *p to the address of j 
  // then r.r will be the reference of j instead the reference of i

  *p = (int64_t)&j;          // int32_t in 32 bit OS; 

  cout << r.r << " " << i << " " << j << endl; // Output: 11 10 11
  return 0;
}

So in fact you can work around to re-assign a reference, like a hacker.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSandeepView Question on Stackoverflow
Solution 1 - C++Brian R. BondyView Answer on Stackoverflow
Solution 2 - C++Martin YorkView Answer on Stackoverflow
Solution 3 - C++PotatoswatterView Answer on Stackoverflow
Solution 4 - C++AnTView Answer on Stackoverflow
Solution 5 - C++Ben MesanderView Answer on Stackoverflow
Solution 6 - C++Jesse EmondView Answer on Stackoverflow
Solution 7 - C++Drew DormannView Answer on Stackoverflow
Solution 8 - C++MSNView Answer on Stackoverflow
Solution 9 - C++Jim FellView Answer on Stackoverflow
Solution 10 - C++tieuthanhliemView Answer on Stackoverflow