References in c++ with function - c++

Could anyone please elaborate the behaviour of reference in this code and why is it printing 12 in first line instead of 11.
Below is the code
http://ideone.com/l9qaBp
#include <cstdio>
using namespace std;
int &fun()
{
static int x = 10;
x++;
return x;
}
int main()
{
int *ptr=&fun();
int *ptr1=&fun();
printf("%p %p \t %d %d",(void*)ptr,(void*)ptr1,*ptr,*ptr1);
return 0;
}
the output of the code is
134519132 134519132 12 12
Please explain why 12 is getting printed on first call not 11 i understand when second call is made it should print 12

ptr and ptr1 are pointing to the same variable static int x. The second call changed the value of static int x to 12, then you print out the value by derefernce ptr and ptr1, the same result will be printed out.

The int reference returned by fun() is the same for both calls (ref to the static x), hence the address of that reference is the same for both calls. Hence the resulting dereference of that identical address is the current identical value.

Your error seems to be in thinking that printf() prints *ptr as soon as it comes available. It does not; printf() is not called until both ptr and ptr1 are computed. Since both ptr and ptr1 point to the same memory location, which is a static variable, and that location is updated after both the first call to fun() and the second, the address holds that value.

static variables have lifetime extent and are stored in statically allocated memory. It means that the storage of static local variables inside a function is not allocated and deallocated on call-stack.
Once x is initialized at compile time, the value of x is kept stored between the invocations of function fun.
As C++ statements are executed sequentially, printf will be executed after the invocations of two function calls in the given lines
int *ptr=&fun();
int *ptr1=&fun();
and therefore the value of x will be 12 before the execution of printf statements.
Keep in mind that
int *ptr=&fun();
int *ptr1=&fun();
is not equivalent to
int& (*ptr)() = &fun;
int& (*ptr1)() = &fun;
In second snippet ptr and ptr1 both holding the address of function fun. In this case you need to call function directly or by using these pointers as
int a = ptr();
int b = ptr1();
after this invocation value of a and b will be 12.

Related

C++ pointers and addresses

i was just playing with pointers as function arguments and i know this.
#include <iostream>
using namespace std;
void func(int *a)
{
*a+=1;
return;
}
int main()
{
int a=1;
cout<<a<<endl;//prints 1
func(&a);
cout<<a;//prints 2
return 0;
}
My question is why does below code act similar to the one above, more precisely
when we call func(&a) from main function in above case
// starting address of that 4 bytes(size of int) of data gets passed and in our function(func) this address is stored in local pointer 'a' and when we write *(a) our compiler knows to read 4 bytes of data because its an integer pointer.
in short, my question is
what exactly are we passing to 'func'
when we call func(a) where 'a' is a variable which stores an integer value
and what exactly func(int &a) means
#include <iostream>
using namespace std;
void func(int &a)
{
//cout<<*a;// error
a+=1;
// cout<<a<<endl;
}
int main()
{
int a=1;
cout<<a<<endl;// prints 1
func(a);
cout<<a;// prints 2
return 0;
}
sorry for bad english
One way to read pointers and references is that during declarations, the '*' can be replaced by "something that points to".
So:
int* a;
Means that 'a' is something that points to an integer (i.e. 'a' is a pointer).
In other places in the code (not declarations), the '*' can be replaced by "the thing pointed to by".
So:
*a = 5;
Means that "thing pointed to by 'a' becomes equal to 5". I.e. the integer which a points to is now 5.
In your first block of code, 'a' is just an integer type. when you write func(&a);, you are passing the address of 'a' (i.e. the name of the memory location which stores the value of 'a') to the function. The function is expecting an int* type, (something which points to an int), which is exactly what you've given it.
Within the function, 'a' is just the address of your variable. The function then takes this address, and says "increment the thing that 'a' points to".
In your secondblock of code, 'a' is again just an integer type. This time however, the function is expecting a reference variable (because the function definition is expecting an int& type.
So within the function, 'a' is the original variable - not a copy or a pointer to the original variable. The function says "increment the actual integer that was sent".
Read more
The two cases work similarly:
Case 1: func expects some pointer to some direction of an integer (int *a) which is, as you said, the first byte of a sizeof (int) bytes block according to the OS. When func is called you passed correctly that direction func(&a), so the compiler considers that call as something like: int p = &a; func(p); anyway a pointer to that direction is actually what is being passed.
Case 2: func expects some direction of some integer (int &a). When func is called you just passed correctly the value func(a), as all C++ compilers support reference paramenters, the compiler passes internally the direction of the passed value, func (&a). Notice if you try to call func like func (&a) an error will occur because it would be passed something like func (&&a) while the compiler is just waiting for (&a).
OBS: We can also look to the second case void func(int &a) as a reference which is different from a pointer with an example:
int a = 10;
int &b = a;
cout<<a; //10 is printed
cout<<b; //10 is printed
b = 20;
cout<<a; //20 is printed
cout<<b; //20 is printed
Whether you modify a reference to a (i.e b) or you modify a directly, you are modifying the same value beacause they stand at the same direction of a.

References - Why do the following two programs produce different output?

I recently read about references in C++. I am aware of basic properties of references but I am still not able to figure out why following two programs produce different output.
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
This program prints 30 as output. As per my understanding, the function fun() returns a reference to memory location occupied by x which is then assigned a value of 30 and in the second call of fun() the assignment statement is ignored.
Now consider this program:
#include<iostream>
using namespace std;
int &fun()
{
int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
This program produces the output as 10. Is it because, after the first call, x is assigned 30, and after second call it is again overwritten to 10 because it is a local variable? Am I wrong anywhere? Please explain.
In the first case, fun() returns a reference to the same variable no matter how many times you call it.
In the second case, fun() returns a dangling reference to a different variable on every call. The reference is not valid after the function returns.
When you use
fun() = 30;
in the second case, you are setting the value of a variable that is not valid any longer. In theory, that is undefined behavior.
When you call fun() the second time in the second case, the variable x is set to 10. That is independent of the first call to the same function.
Just adding to what has been said. The reason behind the first case's behavior is because it is a static variable, which has a static duration. Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends.
This means that once x in the first case has been initialized the first time with 10, the next function call will ignore static int x = 10; because x cannot be instantiated again, as it has already been allocated, and will simply proceed to return x;, which will be the same x that was assigned 30 in main.
Basically, your understanding is right, except for in 2nd case, you're processing a dangled reference of the local variable has been invalid, which is undefined behaviour, means anything is possible. What you said is just one of the possibility, it also could result in others, such as getting a random number, program crash, etc.

Pass by Reference with Pointers

Why this program only works when I initialize a and b.
I want to pass it without initializing a and b, for example:
numChange(10,15);
Is this possible ?
#include <iostream>
using namespace std;
void numChange(int *x,int *y)
{
*x = 99;
*y = 77;
}
int main()
{
numChange(10,15);
//int a=10;
//int b=15;
//numChange(&a,&b);
cout<<a<<" , "<<b<<endl;
return 0;
}
Because you have defined your function to receive pointers, but when you call that function you are trying to pass an int.
The compiler is expecting memory addresses and you are trying to pass constants.
It does not make sense, you are trying to do something like 10 = 99; 15 = 77;?
numChange(10,15);
//int a=10;
//int b=15;
It seems that you are hopping that a = 10 = 99 and b = 15 = 77;
If this was possible, it means that I could never (after the call of numChange(10,15);) make a variable to actually have the value 10 because 10 is "pointing" to 99 (is not).
Recall: a pointer is an integer containing a location in memory.
This:
int a, b;
...
a = b;
copies the integer stored at the memory location reserved for 'b' to
the memory location reserved for 'a'.
This:
int *a, b;
...
a = &b;
stores the location of 'b' in 'a'. Following it with this:
*a = 42;
will store 42 in the memory location stored in 'a', which is the
variable 'b'.
Now, let's look at your code. This:
void numChange(int *x,int *y)
tells the compiler that 'numChange' will be called with two
pointers--that is, memory addresses. This part:
*x = 99;
*y = 77;
then stores two integers at the locations given in 'x' and 'y'.
When you call:
numChange(10,15);
the arguments are integers instead of memory location. However under
the hood, memory locations are also integers so the compiler converts
the arguments to pointers. Effectively, it's doing this:
numChange((int *)10, (int*)15);
(It should issue a warning when this happens, since it's almost never
a good idea, but it will do it.)
Basically, your call to 'numChange' tells it that there are integer
variables at memory addresses 10 and 15, and 'numChange' carries on
and stores integers at those memory locations. Since there aren't
variables (that we know of) at those locations, this code actually
overwrites some other data somewhere.
Meanwhile, this code:
int a=10;
int b=15;
numChange(&a,&b);
creates two integer variables and then passes their addresses in
memory to 'numChange'. BTW, you don't actually need to initialize
them. This works too:
int a, b;
numChange(&a,&b);
What's important is that the variables are created (and the compiler
sets aside RAM for them) and that their locations are then passed to
'numChange'.
(One aside: I'm treating variables as always being stored in RAM.
It's safe to think of them this way but modern compilers will try to
store them in CPU registers as much as possible for performance
reasons, copying them back into RAM when needed.)

Understand Reference and Dereferencing Operators?

Can someone please help me understand Reference and Dereference Operators?
Here is what I read/understand so far:
int myNum = 30;
int a = &myNum; // a equals the address where myNum is storing 30,
int *a = &myNum; // *a equals the value of myNum.
When I saw the code below I was confused:
void myFunc(int &c) // Don't understand this. shouldn't this be int *c?
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum);
cout<< myNum ;
}
int &c has the address to what's being passed in right? It's not the value of what's being passed in.
So when I do c+=10 it's going to add 10 to the memory address and not the value 30. Is that correct?
BUT... when I run this...of course with all the correct includes and stuff...it works. it prints 40.
Actually the ampersand in the function parameter list for myFunc is not an address operator, nor a bitwise and operator. It is a reference indicator. It means that within myFunc, the parameter c will be an alias of whatever argument is passed to it.
You have a few issues here.
your second line of code int a = &myNum; // a equals the address where myNum is storing 30 is wrong;
you can combine it with line 3 like so:
int *a = &myNum; // a equals the address where myNum is stored;
*a == myNum.
The type int & is read as "reference-to-int". Perhaps the Wikipedia article can help you understand what this means.
Both pieces of code are valid and your understanding of pointers in the first piece of code is correct. However, the ampersand (&) in the two pieces of code are actually different things. (Like how * is both the dereference and multiplication operator)
The second piece of code shows how the & can be used to pass variables to a function by reference. Normally if you had code like this:
int a;
void foo(int bar) {
bar = 3;
}
int main() {
a = 5;
foo(a);
// a still equals 5
}
The call to 'foo()' does not affect the variable you passed to it (bar or in this case, a). However if you changed this line:
void foo(int bar) {
to
void foo(int &bar) {
then it would affect the variable and at the end of the program above, the value of a would be 3.
In C++ when you pass things by reference using int &c you don't need to dereference. You only need to dereference pointers. If it was int *c then it would be necessary. Just remember in both cases you change the value of what was passed in the original caller so myNum is now 40.
Let's have a look at the assumptions first:
int myNum = 30;
// this won't compile. &myNum is the address of an int (an int *), not an int:
int a = &myNum;
// *a is a pointer to an int. It received the address of myNum (which is &myNum),
// and not its value
int *a = &myNum;
About the code:
void myFunc(int &c)
// c is passed by reference. This is a kind of "hidden pointer" that
// allows using the variable as if it was not a pointer but the pointed variable.
// But as this reference and the variable that was passed by the caller (myNum
// in your example) share the same address (this is the property of a reference),
// any modification of the value of c inside myFunc modifies it in the
// caller's scope too (so here, it modifies myNum).
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum); // displays 40
// What follows displays 40 as well, due to the fact
// c was passed by reference to myFunc that added 10 to it
cout<< myNum ;
}
So when I do c+=10 it's going to add 10 to the memory address and not
the value 30. Is that correct?
No, 10 was added to the value of c by myFunc.
As c is a reference (a "hidden pointer to") that received myNum, myNum was modified as well.

C++ Pointer Confusion

Please Explain the following code
#include <iostream>
using namespace std;
int main()
{
const int x = 10;
int * ptr;
ptr = (int *)( &x ); //make the pointer to constant int*
*ptr = 8; //change the value of the constant using the pointer.
//here is the real surprising part
cout<<"x: "<<x<<endl; //prints 10, means value is not changed
cout<<"*ptr: "<<*ptr<<endl; //prints 8, means value is changed
cout<<"ptr: "<<(int)ptr<<endl; //prints some address lets say 0xfadc02
cout<<"&x: "<<(int)&x<<endl; //prints the same address, i.e. 0xfadc02
//This means that x resides at the same location ptr points to yet
//two different values are printed, I cant understand this.
return 0;
}
*ptr = 8;
This line causes undefined behavior because you are modifying the value of a const qualified object. Once you have undefined behavior anything can happen and it is not possible to reason about the behaviour of the program.
Since x is a const int, the compiler will most likely, in the places where you use x, directly substitute the value that you've initialized with (where possible). So the line in your source code:
cout<<"x: "<<x<<endl;
will be replaced by this at compile time:
cout<<"x: "<<10<<endl;
That's why you still see 10 printed.
But as Charles explained, the behaviour is undefined, so anything could happen with code like this.