Wrong output of reference to pointer to int - c++

I am trying to use a reference to pointer to int like in below program. But I am not getting the expected output.
Output:
9 5
5 9
Expecting:
9 5
9 5
Code:
#include <iostream>
using namespace std;
void swap (int *& a, int *&b)
{
int *t = a;
a = b;
b = t;
}
int main()
{
int a = 5, b = 9;
int *p = &a;
int *q = &b;
swap (p, q);
cout << *p << " " << *q << endl;
cout << a << " " << b << endl;
return 0;
}
Why is my expectation wrong? I head that reference is nothing just an other name of the target variable.

You swap the pointers, not the values. Your expectation is wrong.

You're swapping the values of the pointers.
Look at this illustration:
First, p is pointing at a, q is pointing at b:
p a
+---+ +---+
+ ------> | 5 |
+---+ +---+
q b
+---+ +---+
+ ------> | 9 |
+---+ +---+
After you swap p and q, q is pointing at a, and p is pointing at b:
q a
+---+ +---+
+ ------> | 5 |
+---+ +---+
p b
+---+ +---+
+ ------> | 9 |
+---+ +---+
But both a and b still have their old values.

In your case, you're swapping the pointers (and not the values). Since you're swapping the pointers, the actual values inside a and b remain unchanged. Hencewhy when you print the value of a, you get 5 and when you print b you get 9.

In general, you are swapping two pointers and not what they point to.
Maybe your function is confusing you as you are calling the values a and b. Your function swaps two pointers such that the first one now points where the second one was pointing, and the second points to where the first was pointing.
p was previously pointing to a and q to b. Now p points to b and q points to a thus your output is 9 5 5 9
There are references in your swap function. These are references to the pointers, so a and b in the function scope become aliases to the parameters passed in, i.e. p and q and thus modify p and q (to point elsewhere).

I head that reference is nothing just a other name of the target
variable
Yes, and target variable in your case is a pointer of the variable, not the variable. Because you're using * in the function declaration. Then, you're swaping pointers not values.
Use one of these ways:
void swap(int &a, int &b)
{
int t=a;
a=b;
b=t;
}
// ...
int a=5,b=9;
swap(a,b);
or
void swap(int *a, int *b)
{
int t=*a;
*a=*b;
*b=t;
}
// ...
int a=5,b=9;
swap(&a,&b);

Related

Value Of Pointers

In my book, it says Pointers are addresses and have a numerical value. You can print out the value of a pointer as cout << (unsigned long)(p)
Write code to compare p,p+1,q, and q+1. Explain the results, Im not sure what the book wants me to so here's what I have. Does anyone Know if I am doing this right
int num = 20;
double dbl = 20.0;
int *p = &num;
double *q = &dbl;
cout << (unsigned long)(q) << endl;
q = q + 1;
cout << (unsigned long)(q) << endl;
cout << (unsigned long)(p) << endl;
p = p + 1 ;
cout << (unsigned long)(p) << endl;
Assuming it's the pointer arithmetic you have problems with, let my try to to show how it's done in a more "graphical" way:
Lets say we have a pointer variable ptr which points to an array of integers, something like
int array[4] = { 1234, 5678, 9012, 3456 };
int* ptr = array; // Makes `ptr` point to the first element of `array`
In memory it looks something like
+------+------+------+------+
| 1234 | 5678 | 9012 | 3456 |
+------+------+------+------+
^ ^ ^ ^
| | | |
ptr ptr+1 ptr+2 ptr+3
The first is technically ptr+0
When adding one to a pointer, you go to the next element in the "array".
Perhaps now you start to see some similarities between pointer arithmetic and array indexing. And that is because there is a common thread here: For any pointer or array p and valid index i, the expression p[i] is exactly the same as *(p + i).
Using the knowledge that p[i] is equal to *(p + i) makes it easier to understand how an array can be used as a pointer to its first element. We start with a pointer to the first element of array (as defined above): &array[0]. This is equal to the expression &*(array + 0). The address-of (&) and dereference (*) operators cancel out each, leaving us with (array + 0). Adding zero to anything can be removed as well, so now we have (array). And finally we can remove the parentheses, leaving us with array. That means that &array[0] is equal to array.
You do it right, if you want to print the decimal representation of the addresses your pointers point to.
If you wonder, why the results are such, you need to learn pointer arithmetic. If you add 1 to any pointer, it's address will be increased by sizeof(<type>), where type is the type of the variable your pointer points to.
So that, if you have a pointer to int and increment it, the address will be increased by sizeof(int), which is, most likely, four.

Multidimensional array

The question is to find the output of the follwing program.
This came out in my test and i got wrong. My answer was 4, 7, 10. The answer is 4,8,12 but i need an explanation on how it works
#include<iostream>
using namespace std;
int main ()
{
int number = 4;
int array[] = {7,8,9,10,11,12,13};
int *p1 = &number ;
int *p2 = array;
int *p3 = &array[3];
int *q[] = {p1,p2,p3};
cout << q[0][0] << endl ;
cout << q[1][1] << endl ;
cout << q[2][2] << endl ;
return 0;
}
What you have is not a multi-dimensional array (C++ doesn't really have it). What you have is an array of pointers. And pointers can be indexed like arrays.
In "graphic" form the array q looks something like this:
+------+------+------+
| q[0] | q[1] | q[2] |
+------+------+------+
| | |
v | v
+------+ | +-----+----------+----------+-----+
|number| | | ... | array[3] | array[4] | ... |
+------+ | +-----+----------+----------+-----+
v
+----------+----------+-----+
| array[0] | array[1] | ... |
+----------+----------+-----+
Some notes:
What most people call multidimensional arrays are actually arrays of arrays. Much like you can have an array of integers, or like in the case of q in your code an array of pointers to integers, one can also have an array of arrays of integers. For more "dimensions" it's just another nesting of arrays.
As for why pointers and arrays both can be indexed the same way, it's because for any array or pointer a and (valid) index i, the expressions a[i] is equal to *(a + i). This equality is also the reason you can use an array as a pointer to its first element. To get a pointer to an arrays first element one can write &a[0]. It's equal to &*(a + 0), where the address-of and dereference operators cancel each other out leading to (a + 0) which is the same as (a) which is the same as a. So &a[0] and a are equal.
q[0] is in fact p1, q[1] is in fact p2 and q[2] is p3.
Now p1 is the address of number so p1[0] is simply the value of number which you correctly computed to be 4.
p2 points to array so p2[1] is the same as array[1] which is the second element in array ot 8.
p3 points to the subarray of array starting from position 3. So p3[2] is the same as array[3 + 2] = array[5] = 12.

what is wrong when i'm trying to access this array (2d ) in c++

below is the code that I'm trying to run
#include <iostream>
using namespace std;
int foo(int **a){
cout<<*(a+3)<<endl;
return 1;
}
int main(){
int a[2][2] = {{1,2},{3,4}};
std::cout << sizeof(a);
foo((int **)a);
}
when I have four elements in this array, shouldn't the value *(a+3) return a value 4, instead of that its returning an address and when i try to dereference that address (i.e. **(a+3)) i get segfault 11
Actually you are defining an array of arrays of integers. It can decay to a pointer to an array of integers, but it will not decay into a pointe to a pointer of integers.
It will help if you draw the memory layout:
+---------+---------+---------+---------+
| a[0][0] | a[0][1] | a[1][0] | a[1][1] |
+---------+---------+---------+---------+
| 1 | 2 | 3 | 4 |
+---------+---------+---------+---------+
If you let it decay into a pointer-to-array-of-integer:
int (*pa)[2] = a;
+---------+---------+---------+---------+
| pa[0] | pa[1] |
+---------+---------+---------+---------+
| 1 | 2 | 3 | 4 |
+---------+---------+---------+---------+
Note how sizeof(*pa) = 2 * sizeof(int). Each of these values can decay into a pointer to integer, but never into a pointer to a pointer:
int *p = pa[0];
Anyway, you can cast the decayed pointer-to-array-of-integer into a pointer to integers and access the four values directly:
int *p = (int*)a;
std::cout << p[3] << std::endl;
std::cout << *(p + 3) << std::endl;
The memory will be like this:
+---------+---------+---------+---------+
| p[0] | p[1] | p[2] | p[3] |
+---------+---------+---------+---------+
| 1 | 2 | 3 | 4 |
+---------+---------+---------+---------+
But if you cast it into a int** you will get meaningless values, because in memory there are no pointers, just integers.
A array is not a pointer. Yes it can decay to a pointer that does not mean it is one. If you want to pass a 2d array then you can use
int foo(int a[][2]);
or if you want to take any size array then you can use
template<std::size_t N>
int foo(int a[][N]);
You are dereferencing too far. a already points to the first element in the array. So **a treats the first value in the array as an address instead of a value. Try
foo((int *)a)
When you dereference int** you get int*. However, you are dereferencing a location with a value 4 that is interpreted as int*. That's why cout prints 0x4, because it formats it as an address. Try taking int* as parameter:
#include <iostream>
using namespace std;
int foo(int *a){
cout<<*(a+3)<<endl;
return 1;
}
int main(){
int a[2][2] = {{1,2},{3,4}};
std::cout << sizeof(a);
foo((int *)a);
}
It prints 4 then.
This is just an example of how to fix up this piece of code in particular, and is not the right way of doing things. Also as #rodrigo stated in the comments of his answer, if the size of an int is not equal to the size of its pointer, this is not going to work. I just wanted to show you why you thought it was printing an address - because it is being interpreted as one.

Strange thing about sizeof [duplicate]

This question already has answers here:
How is the size of a C++ class determined?
(4 answers)
Closed 7 years ago.
Can anyone explain, why size of the objC is 8, not 12?
I think, that if it in the class C I have object with type int and in A, B - char, then after creation of the objC it should be 4 bytes for objA, objB and ObjC.
class A {
char a;
};
class B : A {
char b;
};
class C : B {
int c;
};
int main()
{
A objA;
B objB;
C objC;
cout << sizeof(objA) << endl; // 1
cout << sizeof(objB) << endl; // 2
cout << sizeof(objC) << endl; // 8! Why not 12?
return 0;
}
Edit 1:
In this case sizeof(objC) will be 12:
class A {
char a;
};
class B : A {
int b; // Here is int
};
class C : B {
char c; // Here is char
};
I believe that class C will have:
2x 1-byte chars
2-bytes of padding, so the int starts on a 4-byte boundary.
1x 4-byte integer
Making a total of 8-bytes
To keep the integer aligned on a boundary, there'll be 2-bytes of padding, making 8 bytes.
How do you get 12??
In your second example, class C will have:
a 1-byte char.
3-bytes of padding before the int. (keep the int on a 4-byte boundary)
a 4-byte int.
a 1-byte char.
Making a total of 9-bytes.
Sizes are rounded up to the nearest 4-bytes, which is 12.
In the first case, there is one padding. In the second case there are two paddings.
The first case will be:
+---+---+---+---+---+---+---+---+
| a | b | | | c |
+---+---+---+---+---+---+---+---+
<- 4 ->|<- 4 ->|
The second case will be:
+---+---+---+---+---+---+---+---+---+---+---+---+
| a | | | | b | c | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
<- 4 ->|<- 4 ->|<- 4 ->|

C++ understanding pointers

I have a bit of code that I'm trying to analyze to study up on pointers and I'd like to ask for some help on whether I'm interpreting it correctly and if I'm not can someone help interpret it for me because I still find pointers to be confusing. You will be able to see my interpretations right after the //.
int main()
{
int x = 5;
int y = 3;
int a[] = {5, 10, 15};
PointerMystery(&x, y, a);
cout << x << " " << y << endl;
for (int i = 0; i < 3; i++) {
cout << a[i] << " ";
}
cout << endl;
return 0;
}
void PointerMystery(int *pa, int b, int c[]) {
// *pc will return array c
int *pc = c;
// *pa which returns the address of x will now make x = 20.
*pa = 20;
// b which was 3 is now equal to 15, therefore y = 15
b = 15;
// *pc which returned a array is now 15(im not so sure about this?)
*pc = b;
// im not sure what is happening here either?
pc += 2;
// *pc will return the value (20) - 10?
*pc = *pa - 10;
cout << *pa << " " << b << " " << *pc << endl;
for (int i = 0; i < 3; i++) {
cout << c[i] << " ";
}
cout << endl;
}
Pointer variables are just what their names implies, variables that point to something.
It might be easier to understand if you think about it graphically, and step by step. So...
When the PointerMystery function is called you have the variables pa, b and c:
+----+ +---+
| pa | --> | 5 |
+----+ +---+
+---+
| 3 |
+---+
+---+ +----+----+----+
| c | --> | 5 | 10 | 15 |
+---+ +----+----+----+
After you assign pc you have
+---+
| c | --\
+---+ \ +----+----+----+
>-> | 5 | 10 | 15 |
+----+ / +----+----+----+
| pc | -/
+----+
You then do *pa = 20; so you have
+----+ +----+
| pa | --> | 20 |
+----+ +----+
Then you do *pc = b;, where b is 15, and since pc really just points to the first element of the passed array that mean you change the first element:
+---+
| c | --\
+---+ \ +----+----+----+
>-> | 15 | 10 | 15 |
+----+ / +----+----+----+
| pc | -/
+----+
You then increase the pointer pc to point to the third element of the passed array:
+---+ +----+----+----+
| c | --> | 15 | 10 | 15 |
+---+ +----+----+----+
^
+----+ |
| pc | -------------/
+----+
You then change the value where pc is pointing to the value of where pa is pointing minus 10, and the value of where pa is pointing is 20 which gives 10 after the subtraction:
+---+ +----+----+----+
| c | --> | 15 | 10 | 10 |
+---+ +----+----+----+
^
+----+ |
| pc | -------------/
+----+
Other things that might be good to know about pointers, is that arrays decays to pointers to their first element when you pass them to a function. That's the reason that c is a pointer and where it points.
Also, you can use both array indexing syntax and pointer syntax for both arrays and pointer. You can do this for arrays since they decays to pointers to their first element, and for pointers as a short-hand for *(ptr + x). In fact, for both pointers and arrays, *(ptr_or_array + x) is equivalent to ptr_or_array[x].
The last bit also explains why adding two to the pc pointer makes it points to the third element, *(pc + 0) is equivalent to pc[0] and *(pc + 2) is equivalent to pc[2], which since array indexes are zero based is the third element.