confused about pointers - c++

I just started learning c++ (I'm more of a java developer right now) and am having some confusion with using pointers... for example, the following code works
int main() {
int x = 5;
int * y;
y = &x; //note this line of code
*y = 10;
}
whereas this code does not work
int main() {
int x = 5;
int * y;
y = x;
*y = 10;
}
Can someone explain to me why getting the value "location" using y = &x works but as soon as I replace it with y = x it causes an error. If anyone knows of a good explanation on pointers please share the link :)
Thank you!

Let's see how this works with pointers.
int x = 5;
You're assigning the value 5 to x which is an int.
int *y;
You're declaring a pointer to an int.
y = &x;
Now, the address stored in y is the same as the address of x.
But, if you do this : y = x, you're assigning an integer (5 in that case) to a variable that holds addresses of integers.
Finally, you have to remember that :
& is the address-of operator, and can be read as "address of"
* is the indirection operator, and can be read as "value pointed to by"
Tutorial about pointers

a pointer is a variable that holds a memory location. In your instance, the variable "x" holds the value 5, where the variable y holds a location in memory. the "&" operator will enable you to use the location in memory of the "x" variable
cout >> x; //will give you an output of 5.
cout >> &x; //will give you an output of the memory location of the variable x.
y = &x;
cout >> y; //will give you an output of the memory location of the variable x.

y is a pointer to an int. x is an int. Therefore whenever you set y=x you are telling y that whenever it gets dereferenced, it should go looking at memory location 10 (or whatever x is at assignment time). And there probably isn't a memory allocation at 10. Or at least not what you are expecting. If you want to get the location of x, get a pointer to it with &x.
int main() {
int x = 5;
int * y;
y = &x; // <-- NOTE THE "&" WHICH MEANS GET REFERENCE
*y = 10;
}

Related

What is meaning of (*x++) in c++?

#include <iostream>
using namespace std;
class base {
public:
int* x, y;
base(int xx = 0, int yy = 0) {
x = new int[4];
for (int i = 0; i < 4; i++)
x[i] = 1;
(*x++) = xx;
y = yy++;
}
~base() { delete[] x; }
};
class Derived :public base {
public:
Derived(int xx, int yy) : base(xx), base1(yy) {
cout << (*(this->x)) << " " << this->y << " " << (*
(base1.x)) << " " << base1.y << " ";
}
~Derived() {}
private:
base base1;
};
int main() {
Derived objDev(32, 33);
return 0;
}
I have problem with understand it.
Because i think it should give output as "33 0" but gave "1 0" and also i write in some std::cout for controlling in constructor body, and saw x[3] is -33686019 after '''(*x++) = x; ''' part. How could it be possible? how *x++ can change x[3] and why is this value?
and also compiler give error. doesn't *x++ mean what is x point, increase it? so when after assign xx to (*x++) wouldn't it be 32+1=33?
please help
x = new int[4]; creates an array of 4 int and sets x to point to the beginning of them. Because x is going to change, let’s call this array A, which will not change.
Then x[0] refers to the first element of this array, x[1] is the second, x[2] is the third, and x[3] is the fourth. So far x[0] and A[0] are the same thing, and so are the pairs x[1] and A[1], x[2] and A[2], and x[3] and A[3].
(*x++) is grouped as ( * (x++) ). x++ does two things. It produces the value of x, and, as a side effect, it increments x. Since x++ produces the value of x, *(x++) is the int that x points to before the increment.
This means that (*x++) = xx; stores x in the first element of the array, but it changes x to point to the second element, which is A[1].
Once x points to the second element, then x[0] is A[1], x[1] is A[2], x[2] is A[3], and x[3] is beyond the end of the array. x[-1] would be A[0].
So, where the code sends (*(this->x)) to cout, it is sending A[1], which has 1 in it. That explains why you got output of “1”.
When you looked at x[3], you were looking beyond the array. What is there could be some other value the program has worked with, completely unrelated to what is in the array. But accessing an element beyond array bounds can cause various problems with programs other than just giving a wrong value.
In the destructor, delete[] x; is wrong because x has been changed and no longer has the original address of the array. You could use delete [] --x; or delete [] x-1; to recalculate the original address. However, if a program has some need to use a pointer into the middle of an array, it is more common to store the base address and never change it and create a separate pointer into the middle. That is usually less error prone and easier for other programmers to follow.

Swap integers using pointers

Consider the function :
void swap (int *p,int *q)
{
int temp;
temp=*p;
*p=*q;
*q=temp;
}
swap(4 , 5)
Output:
5 4
I am aware that this is the right way to swap two integers using pointers, as mentioned in the books. But what is actually going on in there? It's very confusing. Consider this function , where the step *p=*q is replaced by p=q i.e., with the indirection operator * removed .
void swap (int *p,int *q)
{
int temp;
temp=*p;
p=q;
*q=temp;
}
Now ,what would happen? In this case the output i get for
swap(4 , 5)
Output:
4 4
Think of an int as a box with a number in it, and think of a pointer as an entry on your clipboard telling you which box to look in.
When you do
*p = *q;
you're looking on your list to find out which box you should use for p, and which box you should use for q; then you're looking what number is in the q box, and copying it into the p box. You still have two separate boxes, and two separate entries on your clipboard; it's just that the two boxes have the same number in.
But when you do
p = q;
you're not touching the boxes at all. You're only changing your clipboard. You're looking up which box you should use for q, and then you're scrubbing out the entry for p on your clipboard and replacing it with the same entry that you found under q. Now you have two boxes, with different numbers in; but your clipboard contains two entries that are the same, and both direct you to the same box. One of your boxes is now unreachable (you don't have an entry on your clipboard pointing you to it), and whenever you look up p or q, you'll end up looking in the same box.
(It's worth noting that this clipboard is only used for executing this particular function, and it gets thrown away afterwards. Changes that you make to the pointers that you pass in as arguments to the function won't have any effect after the function has finished executing. But I'd get your head round the other concepts first off, before you start worrying about scope.)
Because you've removed the step where the int 5 is moved to *p, so you're only moving the 4 across to *q via temp.
Note that int *p and int *q are pointers (represent memory addresses!!). So, when you write p=q you end-up with two pointers that point to the same address!!!
void swap (int *p,int *q)
{
int temp;
temp=*p; // temp = 4
p=q; // p points at the same address with q (where 5 is stored)
*q=temp; // store 4 where q points
}
You now understand that both pointers point to a memory location where integer 4 has been stored! Both pointers point to the same memory location.
In general, the best method for understanding what happens in code with pointers is to bring out a pencil and some paper and start drawing.
I used my computer for this, which is much, much slower.
Since swap(4,5) doesn't actually work, I'll assume that we have two variables in the code that calls swap:
int x = 4;
int y = 5;
swap(&x, &y);
The first two lines of swap are identical in both versions, so the first two pictures apply to both.
As you enter swap, it will look something like this:
As you can see, p points at x, and q points at y.
The value of temp is indeterminate.
Now we have followed the p pointer (*p) and copied the value of x into temp.
Version one:
Here, we follow the pointer q (*q), fetching the value of y (i.e. 5) and then we follow the pointer p (*p) and store that value into x.
And lastly, we follow q so we can store the value of temp, i.e. the value that x used to have, in y.
Version two
Here, we copy the value of q into p.
Since p and q are pointers, they now point to the same thing (y).
As you can see, the variable x hasn't changed; we just changed p so it points somewhere else.
This step is exactly the same as in the first version: store the value of temp in y by following q.
Hope this makes it clearer.
your program will crash because you are passing constant value swap(4,5); and there is no address for 4 and 5what p and q gonna point?
void swap(int *p,int *q){
......
}
expecting two variable to whom pointer p and q can point.
Copy this code to your code editor and test run it. Try to understand what this code is doing using comments.
//Start from main() function
#include <iostream>
using namespace std;
// We are here from main function
/*
This function takes two arguments
both are pointer of type int. When declaring
a pointer of type int we write "int *x". Which means
that the vaiable x is pointer and it can only hold
an address of a varible instead of it's value.
However, We now have addresses of p in x and
q in y. We want to exchange values but taking
addresses of them instead. This is a bit confusing.
*/
void swap(int *x, int *y)
{
int temp = 0;
/*
Things are more confusing in the line below.
" * " is a multipurpose operator.
1. When you put this operator in the middle
of two variable (like a*b ) then it works as a
multipliyer.
2. When you put it when declaring a variable
( like int *x ) then it works as if you are
declaring a pointer of type int.
3. When you put it before a pointer variable name but not
declaring the pointer variable then it gives the
value the pointer pointing to.
In our case the third statement is happening. As x has
the address of p, *x means the value of p.
*/
temp = *x; // Here, *x = 10 (because p = 10) so temp = 10.
/*
Here, we are replacing the value of *x (or p, which is 10)
by *y (or q which is 20).
So, after the execution of the line below
we will have *x = 20 or p = 20. It means we are losing
the previous value of p. This is the reason we kept the value
of p in temp.
*/
*x = *y; // Now p = 20 and q = 20
/*
The line below sets *y (or q ) to the value of temp
(which is 10).
*/
*y = temp; //Now p = 20 and q = 10
}
int main()
{
int p = 0;
int q = 0;
cout << "Enter p : ";
cin >> p; // Say you have entered 10. Now p = 10
cout << "Enter q : ";
cin >> q; // Say you have entered 20. Now q = 20
/*
This line takes you to the swap function above.
We are not sending p, q here. We are sending pointer
or addresses of p and q.
*/
swap(&p, &q); // This line takes you to the swap function above.
cout << "p : " << p << endl;
cout << "q : " << q << endl;
return 0;
}
The function which works correctly:
void swap (int *p,int *q)
{
int temp; //You take an integer variable
temp=*p; //You store the value pointed to by p to temp which is 4
*p=*q; //You copy the value pointed to by q to p which is 5, hence p points to 5
*q=temp; //You store the value in temp as the value pointed by q, hence q points to 4 as temp holds 4
}
Now the code with your changes:
void swap (int *p,int *q)
{
int temp;
temp=*p; //You store the value pointed to by p to temp which is 4
p=q; //p and q are addresses, you equate them so the value pointed becomes equal, if you make change in one the other changes automatically. So basically the value of 'p' in the calling function doesn't change, the change is a local change as the arguments to the called function are passed by reference. So the calue pointed to by p is not altered in 'swap' function.
*q=temp; //Now to make the value pointed to by q as 4
}
You can use the xor swap algorithm:
#include <stdio.h>
int main(int argc, char** argv)
{
int i = 1;
int j = 2;
int *p = &i;
int *q = &j;
printf("BEFORE: %d - %d\n", *p, *q);
if (*p != *q)
{
/* swap */
*p ^= *q;
*q ^= *p;
*p ^= *q;
}
printf("AFTER: %d - %d\n", *p, *q);
return 0;
}
reference:
http://en.wikipedia.org/wiki/XOR_swap_algorithm

C++ : pointers to stack-dynamic variables

I am new to C++. I don't quite understand why this code does not work. What does this code have to do with stack-dynamic variable? Thanks for your help.
int twice(int x)
{
int *y;
*y = x * 2;
return *y;
}
int *y;
*y = x * 2;
is not correct because y points nowwhere, not into an allocated memory. It is undefined behavior. After this line of code your program is completely unpredictable and you cannot assume anything about its behavior.
You need to allocate the memory first using new or malloc and assign x*2 to it or pass an address to assign y into, i.e:
int *y = new int( x * 2);
Example:
int main() {
int x = 4;
int *y = new int( x * 2);
cout << x << "," << *y;
delete y;
return 0;
}
Side note: this is dangerous to return a pointer to memory allocated in function because this might become unclear who and when is responsible for freeing allocated memory. In your particular case there is absolutely no apparent reason for dynamic allocation by the way.

Copying one structure to another and Effect of changing one on Another

#include<stdio.h>
#include<string.h>
struct node
{
int a;
char *p;
};
int main()
{
struct node X,Y;
char s[5] = "Adam";
char t[5] = "Jack";
X.a = 5;
X.p = s;
Y = X;
Y.a = 10;
strcpy(Y.p,t);
printf("%d %s\n",X.a,X.p);
printf("%d %s\n",Y.a,Y.p);
return 0;
}
In this Question , Structure X has "a=5" and "P pointing to Adam". and then this is copied to another structure Y. and changes are made to Y.
But when strcpy(Y.p,t) is done .
OUTPUT IS :
5 Jack
10 Jack
This change is supposed to be only in Y , but these changes are also reflected for X. How so ?
MY question is "How does changing one structure member have effect on another when they are copied " ?
You initialized Y as copy of X. That means it contains the same pointer in the p field - you didn't ever change that.
When you do the strcpy, you're writing the contents of t overtop of s.
You're lucky you picked two 4-letter names...
strcpy(Y.p,t);
Y.p value is the same as the value of s. So the above function call is actually the same as:
strcpy(s, t);
This is because the character pointer p of both structures X and Y points to the same memory location.
so strcpy changes the data for both X and Y

How to convert int* to int

Given a pointer to int, how can I obtain the actual int?
I don't know if this is possible or not, but can someone please advise me?
Use the * on pointers to get the variable pointed (dereferencing).
int val = 42;
int* pVal = &val;
int k = *pVal; // k == 42
If your pointer points to an array, then dereferencing will give you the first element of the array.
If you want the "value" of the pointer, that is the actual memory address the pointer contains, then cast it (but it's generally not a good idea) :
int pValValue = reinterpret_cast<int>( pVal );
If you need to get the value pointed-to by the pointer, then that's not conversion. You simply dereference the pointer and pull out the data:
int* p = get_int_ptr();
int val = *p;
But if you really need to convert the pointer to an int, then you need to cast. If you think this is what you want, think again. It's probably not. If you wrote code that requires this construct, then you need to think about a redesign, because this is patently unsafe. Nevertheless:
int* p = get_int_ptr();
int val = reinterpret_cast<int>(p);
I'm not 100% sure if I understand what you want:
int a=5; // a holds 5
int* ptr_a = &a; // pointing to variable a (that is holding 5)
int b = *ptr_a; // means: declare an int b and set b's
// value to the value that is held by the cell ptr_a points to
int ptr_v = (int)ptr_a; // means: take the contents of ptr_a (i.e. an adress) and
// interpret it as an integer
Hope this helps.
use the dereference operator * e.g
void do_something(int *j) {
int k = *j; //assign the value j is pointing to , to k
...
}
You should differentiate strictly what you want: cast or dereference?
int x = 5;
int* p = &x; // pointer points to a location.
int a = *p; // dereference, a == 5
int b = (int)p; //cast, b == ...some big number, which is the memory location where x is stored.
You can still assign int directly to a pointer, just don't dereference it unless you really know what you're doing.
int* p = (int*) 5;
int a = *p; // crash/segfault, you are not authorized to read that mem location.
int b = (int)p; // now b==5
You can do without the explicit casts (int), (int*), but you will most likely get compiler warnings.
Use * to dereference the pointer:
int* pointer = ...//initialize the pointer with a valid address
int value = *pointer; //either read the value at that address
*pointer = value;//or write the new value
int Array[10];
int *ptr6 = &Array[6];
int *ptr0 = &Array[0];
uintptr_t int_adress_6 = reinterpret_cast<uintptr_t> (ptr6);
uintptr_t int_adress_0 = reinterpret_cast<uintptr_t> (ptr0);
cout << "difference of casted addrs = " << int_adress_6 - int_adress_0 << endl; //24 bits
cout << "difference in integer = " << ptr6 - ptr0 << endl; //6