Why does the address of pointer changes while passing? - c++

while implementing the BST by my own using struct, I got confused on how the pointer works.
here’s my simple code
#include <iostream>
#include <vector>
using namespace std;
void ptr_change(int* p){
cout<<&p<<endl;
/*
*address changes. why ? */
return ;
}
int main(){
//4. Pointer address integrity
cout<<"4. Pointer address integrity"<<endl;
int* p1;
cout<<&p1<<endl;
ptr_change(p1);
}
Why does the address changes when after passing it to the function as parameter??
Thank U!

The address didn't change. You're looking at two separate variables.
In the main function, you define a variable called p1. This variable has a particular address. You then pass the value of p1 to the function ptr_change.
In ptr_change, it has a parameter called p. This variable has its own address separate from p1 in main, although it contains the same value as p1.
You may be confused because the parameter in question is a pointer. It's no different than a non-pointer parameter. For example:
void foo(int x)
{
cout << &x << end;
}
int main()
{
int y = 0;
cout << &y << end;
foo(y);
return 0;
}
Here, x in foo and y in main are different variables each with their own address, but they both contain the value 0.

You are passing a copy of the pointer to the function. It's like when you pass a -say- int variable, you pass a copy of it's value. When you pass a pointer to int, you are copying the pointer itself, which also points to the same memory location, but pointer itself can be stored at another random location.

Related

Function returns null pointer instead of address

I'm playing around with pointers to understand this concept better
and wanted to ask
Why do i get null pointer as return for the second function?
and why it isn't possible to get the address 0x7fff15504044.
What is happening and where inside memory is the integer 5 stored,
when im working with it inside the function?.
#include <iostream>
using namespace std;
int* return_adress(int* input){ return input; }
int* return_adress_from_input(int input){ return &input; }
int main(){
int k = 3;
cout << return_adress(&k) << endl;
cout << return_adress_from_input(k) << endl;
}
Output:
0x7fff15504044
0
With int* return_adress_from_input(int input), input is a value copy of k in the caller. They are two different variables therefore with different addresses.
input goes out of scope conceptually once the closing brace of the function is reached.
The pointer &input then points to memory that you no longer own, and the behaviour of reading that pointer value (let alone dereferencing it) is undefined prior to C++14, and implementation defined from and including C++14.
Because you pass input by value, not by reference. Compiller first creates a local copy of input and then returns address of this local copy. To get the variable address use
int* return_adress_from_input(int& input){ return &input; }
In general, you get undefined behavior which can lead to returning nullptr in the particular case
On my PC i get
00AFFC80
00AFFBA8
so you are just lucky with zero return

Changing address of variables using reference

in below code why its displaying 2,3 though we change the address. why not 3,2.
#include <iostream>
using namespace std;
void Addresschange(int *a, int *b)
{
int *t;
t = a;
a = b;
b = t;
cout << *a<<endl<< *b<<endl;//here its displaying 3,2
}
int main ()
{
int a = 2 ,b = 3;
Addresschange(&a ,&b);
cout << a<<endl<< b;//why its displaying 2,3 here
return 0;
}
So after going out of this function the addresses of the actual parameters (a and b) would be changed. Is it possible at all?
In the Addresschange function, a and b are local variables. When you change their values, that only changes their values inside the function. So your code just swaps the values of a and b inside the Addresschange function. It doesn't use any pointer operations, so even though the values happen to be pointers. that doesn't change the fact that they're passed by value and that means that changing the value won't propagate out of the function.
If you want to change something's value using a pointer, you have to pass a pointer to it and change the value the pointer points to. So if you want to change the value of an int *, you need to pass the function an int **.
Your function passes an int * (pointer to int), which lets you change the value of an int. For example, *a = 3; will make a equal to 3 instead of 2 in the caller, using the pointer that was passed by value to change the value of the thing it points to.
(You can also use references in C++. You still can't "reseat" a reference to make it refer to something else unless you use something like std::reference_wrapper.)

Pointer Confusion with C++

I am very confused with c++ pointers and reference operators. My main confusion is the following (simple ) code:
#include <iostream>
using namespace std;
void changeInt(int &a)
{
a *= 3;
}
int main()
{
int n = 3;
changeInt(n);
cout << n << endl;
return 0;
}
Mainly, I am confused as to why changing the address (&a) changes the actual variable (n). When I first attempted this problem this was my code:
#include <iostream>
using namespace std;
void changeInt(int &a)
{
*a *= 3;
}
int main()
{
int n = 3;
changeInt(n);
cout << n << endl;
return 0;
}
But this gives me an error. Why is it that when I change the address it changes the variable, but when I change the value pointed by the address I get an error?
Your second example is not valid C++, you can only dereference a pointer (or an object whose type overload operator*, which is not your case).
Your first example pass the parameter by reference (int &a is not "the address of a", it is a reference to a), which is why a change to a really is a change to the object being passed by the function (in you case, n)
The ampersand (&) in that context means a reference, not the "address". E.g.:
int some_int;
int & a = some_int; // Declare 'a', a reference to 'some_int'
int * p = &some_int; // '&' in this context is "the address of" 'some_int'
A reference is equivalent to a pointer in many ways, but it behaves like a value type.
See this thread and the wikipedia entry to learn more.
The ampersand indicates that a variable is passed by reference to your function -- but inside the function the variable is treated as if it were passed by value. This is syntactic sugar, to make writing code that accepts references simpler to understand.

C++ Passing Struct Address

Im a little bit confused about passing structs into functions. I understand pointers and everything.
But for instance:
struct stuff
{
int one
int two
};
int main{
stuff fnc;
fnc.two = 2;
fnc.one = 1;
multiply(&fnc);
}
void multiply(const stuff * pm){
cout << pm->one * pm->two;
}
First of all....am i even doing this right.
And second of all, why do we use the address operator when we pass the function, but use the * pointer operator in the actual function call?
Im confused?
Yes, your code is compilable other than the missing semicolons in the defintion of struct stuff. I'm not quite sure exactly what you're asking about passing the function and the actual function call, but I think you're wondering why the function call uses &fnc, but the parameter is stuff *pm? In that case, the fnc variable declared is a plain stuff. It is not a pointer, it refers to the actual instance of that struct.
Now the multiply function is declared as taking a stuff* -- a pointer to a stuff. This means that you can't pass fnc directly -- it's a stuff and multiply expects a *stuff. However, you can pass fnc as a stuff* by using the & operator to take the address, and &fnc is a valid stuff* that can be passed to multiply.
Once you're in the multiply function, you now have a stuff* called pm. To get the one and two variables from this stuff*, you use the pointer to member operator (->) since they are pointers to a stuff and not a plain stuff. After obtaining those values (pm->one and pm->two), the code then multiples them together before printing them out (pm->one * pm->two).
The * and & operands mean different things depending on whether they describe the type or describe the variable:
int x; // x is an integer
int* y = &x; // y is a pointer that stores the address of x
int& z = x; // z is a reference to x
int a = *y; // a in an integer whose value is the deference of y
Your pm variable is declared as a pointer, so the stuff type is modified with *. Your fnc variable is being used (namely for its address), and thus the variable itself is marked with &.
You can imagine the above examples as the following (C++ doesn't actually have these, so don't go looking for them):
int x;
pointer<int> y = addressof(x);
reference<int> z = x;
int a = dereference(y);
It the difference between describing a type and performing an operation.
In
void multiply(const stuff * pm){
cout << pm->one * pm->two;
}
The stuff * pm says that pm is an address of a stuff struct.
The
&fnc
says "the address of fnc".
When a variable is declared like:
stuff *pm;
it tells us that pm should be treated like an address whose underlying type is stuff.
And if we want to get the address of a variable stuff fnc, we must use
&fnc
You need the address of operator so you can get the address of the object, creating a pointer, which the function expects. The '*' in the parameter list is not a pointer operator, it simply says that the variable is a pointer.
Your code is correct. In the main, you successfully create a 'stuff' object and set its values. Then, you pass a constant address to the object into the function multiply. The multiply function then uses that address to access the two variables of the structure to output the multiplication of the variables.
The * in "const stuff * pm" means that it takes a constant pointer to a stuff object.
Here is a working example of what you would like to see.
#include <iostream>
using namespace std;
struct stuff
{
int one;
int two;
};
void multiply(stuff* pm)
{
cout << pm->one * pm->two;
}
int main()
{
stuff* fnc = new stuff;
fnc->two = 1;
fnc->one = 2;
multiply(fnc);
delete fnc;
cin.ignore(1000, 10);
return 0;
}
Sure, this would work, aside from your erroneous main function definition.
The reason why this works is because when you use the unary & operator, it essentially returns a pointer to the operand, so in your case, fnc, which is of type stuff, if you did &fnc, that would return a stuff *. This is why the multiply function must take in a stuff *.
struct stuff
{
int one, two;
};
int main(int argc, const char* argv[]) {
stuff fnc;
fnc.two = 2;
fnc.one = 1;
multiply(&fnc); //passes a pointer to fnc
}
void multiply(const stuff * pm){
//the "*" operator is the multiplication operator, not a pointer dereference
cout << pm->one * pm->two; //->one is equivalent to (*pm).one
}
You have a couple of syntactic errors in your program, but other than that, the basic idea is fine. Here are the syntax problems I had to fix before your program would compile:
#include <iostream>
using namespace std;
struct stuff
{
int one;
int two;
};
void multiply(const stuff * pm) {
cout << pm->one * pm->two;
}
int main() {
stuff fnc;
fnc.two = 2;
fnc.one = 1;
multiply(&fnc);
}
To answer your questions about difference between the '&' (address of) operator and the '*' (pointer dereference) operator though, we just need to think about the types you're passing in to the function.
Take the function multiply:
void multiply(stuff *fnc) {
...
}
In the definition of this function, you are describing something that takes a pointer to a stuff struct. In that first line, you aren't saying you are dereferencing that object, just that you are expecting a pointer to a stuff object.
Now when you call multiply:
stuff fnc;
multiply(&fnc);
You are using the '&' (address of) operator to get a pointer to the object. Since the multiply function expects a pointer, and you have the plain old object, you need to use the & operator to get a pointer to give to the multiply function.
Perhaps it is clearer to think call it like this:
stuff fnc; //The actual object
stuff* fnc_ptr = &fnc; //A pointer to a stuff object, initialized to point at fnc created above
multiply(fnc_ptr); //Call the function with the pointer directly
Following code will tell you about the pointer illustration
A struct address is passed into the function named multiply and this
function perform some operations with the element of the passed
structure and store the result in the result variable.
you can see here clearly that the result variable is previously zero then after passing the address of the structure to the function multiply the result variable value gets updated to value 6. this is how pointer works.
#include <iostream.h>
struct stuff
{
int one;
int two ;
int result;
};
void multiply(stuff *pm);
int main(){
stuff fnc;
fnc.two = 2;
fnc.one = 3;
fnc.result = 0;
multiply(&fnc);
cout<<fnc.result;
return 0;
}
void multiply(stuff *pm)
{
pm->result = pm->one * pm->two;
}

Confusion about pointers and their memory addresses

alright, im looking at a code here and the idea is difficult to understand.
#include <iostream>
using namespace std;
class Point
{
public :
int X,Y;
Point() : X(0), Y(0) {}
};
void MoveUp (Point * p)
{
p -> Y += 5;
}
int main()
{
Point point;
MoveUp(&point);
cout << point.X << point.Y;
return 0;
}
Alright, so i believe that a class is created and X and Y are declared and they are put inside a constructor
a method is created and the argument is Point * p, which means that we are going to stick the constructor's pointer inside the function;
now we create an object called point then call our method and put the pointers address inside it?
isnt the pointers address just a memory number like 0x255255?
and why wasnt p ever declared?
(int * p = Y)
what is a memory addres exactly? that it can be used as an argument?
p was declared.
void MoveUp (Point * p)
{
p -> Y += 5;
}
is a function that will take a pointer to a Point and add 5 to its Y value. It's no different to the following:
void f(int n) {
printf ("%d\n", n);
}
:
int x = 7;
f(x);
You wouldn't say n wasn't defined in that case. It's the same for p in your case.
Perhaps some comments in the code would help:
#include <iostream>
using namespace std;
class Point
{
public :
int X,Y;
Point() : X(0), Y(0) {} // Constructor sets X and Y to 0.
};
void MoveUp (Point * p) // Take a Point pointer p.
{
p -> Y += 5; // Add 5 to its Y value.
}
int main()
{
Point point; // Define a Point.
MoveUp(&point); // Call MoveUp with its address.
cout <<point.X << point.Y; // Print out its values (0,5).
return 0;
}
Pointers are simply a level of indirection. In the code:
1 int X;
2 int *pX = &X;
3 X = 7;
4 *pX = 7;
the effect of lines 3 and 4 are identical. That's because pX is a pointer to X so that *pX, the contents of pX, is actually X.
In your case, p->Y is the same as (*p).Y, or the Y member of the class pointed to by p.
A pointer is simply a variable like any other but it holds a memory address.
Read that line about 6 times. The name pointer itself seems scary to people, but it is really just called this to make it easier for ourselves to think about what is happening.
The type of a pointer (for example char*, int*, Point*) simply tells the compiler what is stored at that memory address.
So all pointers are alike in that they all store a simple memory address. But they are different in that the type of the pointer will tell you what will be contained at that memory address.
and why wasnt p ever declared?
p is declared:
//p is declared to be a variable that holds an address
// and at that address it holds a type Point
//p itself only holds an address not the actual data of the Point.
void MoveUp (Point * p)
{
//The -> operator when applied to a pointer, means give me the object at
// that address and then access the following member
p->Y += 5;
}
what is a memory addres exactly? that it can be used as an argument?
You can think of a memory address simply as a number. On 32-bit programs this number is 4 bytes long. On 64-bit programs this number is 8 bytes long.
Consider the following code:
Point point;
Point *p = &point;
The point variable is of type Point. It holds an object of the class Point.
The &point expression returns an address of the Point variable point. The expression &point is of type Point*.
The p variable holds a address of type Point, the type of p is Point*. p holds the address in memory of the object point.
p is declared in the function definition
void MoveUp (Point * p)
Before you look at pointers, you have to clarify for yourself the meaning of "class", "instance" and "constructor". Your sentence
a class is created and X and Y are
declared and they are put inside a
constructor
shows the need for such clarification. Here is a discussion on books you may want to read: Books to refer for learning OOP through C++
Think about memory as contiguous small blocks.
Now, think about the Point class as something that is 2 blocks width, and you put it in any place of the memory. It doesn't matter where, the important thing is that it is placed in only ONE starting point. You can move it and change that staring point, but irrevocably will start in ONE starting point.
Then the pointer is the number of that ONE starting point.
When you pass a pointer as an argument, you doing
you: 'hey function, take this Point and do what you know!'
function: 'ok, but where is the Point!?'
you: 'oh, sorry, i don't take it with me, it's located there, in that block!'
And the function will know now that THERE is a Point, and with the magic of the compiler, the function will know that its 2 blocks width. Then the function takes it, change its Y (thanks again, compiler), and leave it where it was before (in fact, it didn't even take it away from there).
Minutes later, you go there, and see Point.Y has changed. You say 'thanks', and you go.
p was declared as a method parameter.
Pointers are a special kind of variable that hold the memory address of a value. The * symbol is the dereference symbol, which tells your code to go lookup the value IN the memory address held by the pointer. Now is also a good time to introduce the & symbol, which tells your code to get the memory address of a value. For example:
int i = 5; //int
int *pointer; //int pointer
pointer = &i; //sets pointer to the memory address of i
doMath(&i); //passes a memory address, value inside that address is being used
doMath(pointer); //same as above
dontMath(i); //value of x will be 207, value of i is still 7 since a copy is being modified
//value of pointer is a memory address
//value of *pointer is the value stored inside that memory address, 7
//value of &pointer is the memory address of pointer, which itself holds the memory address
void doMath(int *p) {
*p++;
}
void dontMath(int x){
x=x+200;
}
The confusion I had early on was the meaning of the * symbol. In variable declaration, it means that your are declaring a pointer for a certain datatype (a variable that holds a memory address). Elsewhere, it is the dereference symbol telling your code to resolve the value.