C++ '&' Operator: Understanding the Difference Between Memory Addresses and Aliases (References)

Revision en5, by TryOmar, 2023-01-12 03:18:45

& operator function differently in the context of variable assignment and memory address

int y = 30; 
int &x = y;  // What is x?
cout << (&x); // What are we printing?

In the above example, the & operator is used for two distinct purposes and is important to note that the usage of & in int &x = y; is not the same as in cout << (&x); What is the difference between the two usage and how they work internally?

The & operator in C++ has two main uses: as an alias (reference) and as a memory address.

First, let's explain the following code:

int main(){
    int y = 30; // Declare and initialize a variable y with the value 30
    int &x = y; // Declare a reference variable x that references y
    cout << (&x); // Print the memory address of x (which is the same as the memory address of y)
}

Here, int &x = y declares a reference variable x that refers to the existing variable y. This means that x and y are aliases for the same memory location, so any changes made to x are also made to y and vice versa. However, cout << (&x); is printing the memory address of x (and thus y), not the value of x or y (which is 30).

Let's look at another example of using & as an alias:

void increment(int& x) {
    x++;
}

int main() {
    int y = 5;
    int& r = y; // Declare a reference r that references y
    increment(r);
    cout << y << endl;  // y will now be 6
}

In this example, the increment function takes a reference x as an argument, which is an alias to the variable passed in. The main function passes the variable y directly to the function, which increments the value of y by using x.

Finally, consider the following example of using & for returning an alias from a function:

int& getNumber() {
    int x = 5;
    return x;
}

int main() {
    int& r = getNumber();
    cout << r << endl;   // This will lead to undefined behavior, as the reference r will be a dangling reference
}

This function creates a new integer variable on the stack and assigns it the value 5. However, since the variable x is local to the function, it will be deallocated after the function returns, so the reference r will be a dangling reference, accessing its value will lead to undefined behavior.

To make the function return an actual reference, we can move x from being a local variable to a global variable:

int x = 5;
int& getNumber() {
    return x;
}

int main() {
    int& r = getNumber();
    cout << r << endl;   // This will print 5, as r is now a valid reference to the global variable x
}

My use-case while solving a problem

I made a practical application for the reference function, it can be helpful (I'm no sure if someone knew this before, write me in the comment)

#include <iostream>
using namespace std;

int frq[10]; // example array

int &fr(int x) {
    return frq[x-1];
}

int main() {
    fr(5) = 10; // equivalent to frq[5-1] = 10;
    cout << fr(5) << endl; // prints 10
    fr(5)++; // equivalent to frq[5-1]++;
    cout << fr(5) << endl; // prints 11

    return 0;
}

In programming, it's often useful to have shorthand notation for commonly-used operations. The function int &fr(int x) allows for just that when working with an array called frq.

This function returns a reference to the frq[x-1] element in the frq array. This means that instead of using the syntax frq[x-1] to access and modify elements in the array, you can use the shorthand fr(x).

For example, instead of writing frq[x-1]++ to increment the frequency of the element x, you can write fr(x)++.

So this function helps make your code more concise and readable, and shorter.

Summary: It's worth mentioning that returning reference from a function is a bit risky as it may lead to many unintended behaviors if not handled carefully, but I believe you can do fun things with it.

Tags c++, reference, alias, memory address, pointer, reference function, scope, function return, frequency array, index - 1

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en5 English TryOmar 2023-01-12 03:18:45 5 Tiny change: 'n\n### My UseCase while ' -> 'n\n### My use-case while '
en4 English TryOmar 2023-01-11 09:37:40 169
en3 English TryOmar 2023-01-11 09:19:37 4 Tiny change: 'e.\n\n\n\nSummary: I' -> 'e.\n\n\n\n*Summary: I'
en2 English TryOmar 2023-01-11 09:06:25 103 Tiny change: '### `&` operat' -> '`&` operat'
en1 English TryOmar 2023-01-11 08:40:59 4382 Initial revision (published)