1

I came across a C++ code snippet in my exams which was quite confusing (at least for me). I tried to analyze it but there is something that I am unable to understand. The code is written below:

#include <iostream>

using namespace std;

int* doMagic(int *p, int *q)
{
    int* t = new int();
    t = p;
    p = q;
    q = t;
    return t;
}

int main()
{
    int p = 5, q = 10;
    int *t = NULL;
    t = doMagic(&p, &q);
    cout<<"p = "<<p<<endl;
    cout<<"q = "<<q<<endl;
    cout<<"t = "<<*t<<endl;
    return 0;
}

The output is:

p = 5
q = 10
t = 5

Now my question is that when the values were passed by reference to doMagic function why weren't the values swapped in it.

Help will be highly appreciated.

Thanks.

malik727
  • 169
  • 8
  • 4
    You do not use any reference in your code. And to do swap using pointers you should change *pointee* values, not pointers themselves. I suggest you ditch your current learning source and get [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to learn C++. – Yksisarvinen Dec 17 '19 at 18:03
  • 4
    `doMagic` takes its arguments by *pointer*, *not* by reference. You are swapping pointers, not what the pointers point to. – Jesper Juhl Dec 17 '19 at 18:04
  • Also; look up [std::swap](https://en.cppreference.com/w/cpp/algorithm/swap). Swapping two values efficiently is a *solved* problem. There's no need for you to reinvent the wheel. – Jesper Juhl Dec 17 '19 at 18:06
  • pointers are passed by value, most stuff going on in `doMagic` has no effect – 463035818_is_not_an_ai Dec 17 '19 at 18:07
  • Also; remember that C++ is a *context sensitive* language. `&` means different things in different contexts. In some contexts it means "reference", in others it means "address of". – Jesper Juhl Dec 17 '19 at 18:08
  • @JesperJuhl Firstly, I mentioned that I came across this question in the exam so I am not reinventing the wheel & Secondly we are swapping the address of `p` & `q` so the values should also be swapped naturally. – malik727 Dec 17 '19 at 18:08
  • 1
    @Gingitsune you are just swapping the values/addresses stored in some function-local variables (`p`, `q` & `t` are all *function-local* variables, all holding an address of something and you are just swapping addresses between variables). That doesn't swap what they point to. – Jesper Juhl Dec 17 '19 at 18:11
  • oh, I understand ... thanks, mate – malik727 Dec 17 '19 at 18:12
  • 1
    I hope the question was something like "find all the problems in this code", because it's horrible. – Pete Becker Dec 17 '19 at 18:13
  • 1
    `int *t = NULL;` - better --> `int *t = nullptr;` – Jesper Juhl Dec 17 '19 at 18:21
  • 1
    Btw; you do know that `endl` flushes the stream, right? If you just want a newline, then `'\n'` is more efficient for the first printouts until you *really* also want a flush. Doesn't matter for a trivial program, but, I've seen pointless flushes seriously degrade performance in real life programs. Don't do more work than you intend. – Jesper Juhl Dec 17 '19 at 18:26

2 Answers2

3

The variables p and p in doMagic are local to the function. Any changes made to those variables are made locally in the function. They don't change anything in the calling function.

You can rename those variables to x and y without changing the function's behavior. That will also be a reminder that the names in main and the name in doMagic are separate and independent.

You can swap the values in doMagic by swapping the values of the objects the pointers point to:

void doMagic(int *p, int *q)
{
    int t = *p;
    *p = *q;
    *q = t;
}

although it is idiomatically better C++ to use references

void doMagic(int& p, int& q)
{
    int t = p;
    p = q;
    q = t;
}

Then, the function can be called from main as:

doMagic(p, q);

Having said that, if you don't intend to do anything more in the function, you should use std::swap instead. There is nothing to gain by defining a function in user space that duplicates the functionality of a standard library function.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

In this code nothing gets passed by reference.

Some pointer values (&p, &q) get passed by value.

Because they were passed by value, they were stored into new variables in doMagic called p and q. The new variables were then swapped. The value &p was returned and stored in main's variable t.

Also, some memory was leaked, because an int was created with new and was never destroyed with delete.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
user253751
  • 57,427
  • 7
  • 48
  • 90