How does this operation on pointers work? - c++

int x = 4;
int* q = &x; // Is it always equivalent to int *q = &x; ?
cout << "q = " << q << endl; // output: q = 0xbfdded70
int i = *q; // A
int j = *(int*)q; // B, when is this necessary?
cout << "i = " << i << endl; // output: i = 4
cout << "j = " << j << endl; // output: j = 4
My question is what does lines A and B do, and why the outputs are both 4?

It is a basic usage of pointers, in A you dereference pointer (access the variable to which a pointer points)":
int i = *q; // A
while B is doing exactly the same but it additionally casts pointer to the same type. You could write it like that:
int j = *q; // B
there is no need for (int*)

int x = 4;
x is 4
int* q = &x;
q is the memory location of x (which holds 4)
cout << "q = " << q << endl; // output: q = 0xbfdded70
There's your memory location.
int i = *q; // A
i is the value at memory location q
int j = *(int*)q; // B
j is the value at memory location q. q is being cast to an int pointer, but that's what it already is.

int i = *q; // A
Dereferences a pointer to get the pointed value
int j = *(int*)q; // B
type casts the pointer to an int * and then dereferences it.
Both are same because the pointer is already pointing to an int. So typecasting to int * in second case is not needed at all.
Further derefenecing yields the pointed integer variable value in both cases.

Lines A and B are equivelent as q is already an int* and therefor (int*)q equals q.
int i = *q; yelds that i becomes the value of the integer pointed to by q. If you want to make i to be equal to the adress itself remove the asterisk.

A: Dereference - takes a pointer to a value (variable or object) and returns the value
B: Cast to int* and than dereference
The result is the same because the pointer is already to int. That's it.

Line A takes the value that q points to and assigns it to i. Line b casts q to the type int* (which is q's type already, so that cast is entirely redundant/pointless), then takes the value that q points to and assigns it to j.
Both give you 4 because that's the value that q points to.

Line A de-reference pointer q typed as int *, i.e. a pointer points to an int value.
Line B cast q as (int *) before de-reference, so line B is the same as int j = *q;.

Related

Reference in C++

Suppose that we have these two situations?
int p = 10;
int& q = p;
and
int p = 10;
int q = p;
Are not these two situations the same? I am little confused with the purpose of references, so please explain difference in these two.
int p = 10;
int& q = p;
In this case, q is for all practical purposes an alias for p. They share a memory location. If you modify q, you modify p. If you modify p, you modify q. q is just a different name for p.
int p = 10;
int q = p;
Here, q gets a copy of the value of p at the time when q is initialized. Afterwards, q and p are completely independent. Changing q does not affect p and changing p does not affect q.
In the second case, if you change the value of q it will not affect the value of p. In the first case, changing the value of q will also change the value of p and vice versa.
$ cat ref.cpp
#include <iostream>
int main () {
int p = 10;
int q = p;
int s = 10;
int& t = s;
q = 11;
t = 11;
std::cout << p << std::endl;
std::cout << q << std::endl;
std::cout << s << std::endl;
std::cout << t << std::endl;
s = 12;
std::cout << s << std::endl;
std::cout << t << std::endl;
}
$ g++ ref.cpp
$ ./a.out
10
11
11
11
12
12
$
In Second case p q are two independent integers. in first case both p q will point to same location in the memory. as you asked for the purpose of references. please go through call by value & call by reference. you can understand the use of references. go through the page. http://www.tutorialspoint.com/cplusplus/cpp_function_call_by_reference.htm
Changing a reference will change the underlying variable. This can be useful
in situations like:
int count_odd = 0;
int count_even = 0;
int i;
....
// Create a reference to either count_odd or count_even.
int& count = (i%1) ? count_odd : count_even;
// Now update the right count;
count++;
This is rather artificial, but it becomes more useful with rather more
complicated situations.

Dereferencing a pointer gives an address

i have this code snippets
const int col= 5;const int row= 5;
int a[row][col] = {0};
int (*p)[col] ;
p = a;
And these statements print the same address
cout <<p;
cout << endl;
cout << *p;
in my opinion since p points to an array of 5 ints, dereferencing it
should give the first value which doesn't seem to be the case.
help!
since p points to an array of 5 ints
That much is correct.
dereferencing it should give the first value
No, it's type is "pointer to array"; dereferencing that gives "array", which decays to an int* pointer when you do just about anything with it - including printing it.
If you had a pointer to int
int * p = a;
then *p would indeed give the first array element.

array of constant pointers

Ok, I know that this is invalid
char char_A = 'A';
const char * myPtr = &char_A;
*myPtr = 'J'; // error - can't change value of *myP
[Because we declared a pointer to a constant character]
Why is this valid?
const char *linuxDistro[6]={ "Debian", "Ubuntu", "OpenSuse", "Fedora", "Linux Mint", "Mandriva"};
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
*linuxDistro="WhyCanIchangeThis";// should result in an error but doesnt ?
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
Thanks for looking!
You write
*linuxDistro = "WhyCanIchangeThis";
which is perfectly valid, because the declaration of linuxDistro was
const char *linuxDistro[6];
i. e. it's an array of 6 pointers to const char. That is, you can change the pointers themselves, just not the characters pointed to by those pointers. I. e., you can not compile
*linuxDistro[0] = 'B';
to obtain the string "Bebian", becuse the strings contain constant characters...
What you probably want is an array of constant pointers to constant characters:
const char *const linuxDistro[6];
*linuxDistro is still a pointer, it is linuxDistro[0], *linuxDistro="WhyCanIchangeThis" it just change the pointer to point to a new address, not to modify the content in the old address, so it is OK.
If you write **linuxDistro='a', it should error.
because the pointer is a variable that stores a memory address, if a pointer is const the pointer keeps storing the same memory address, so the value of the pointer itself can't change, but you are saying nothing about the value pointed by the pointer, according to what you have, chaging the pointed value it's an allowed operation.
because char is not char[], so when you access to * of char[] you access the first element of it (Debian).
when you shift pointer (e.g. +1 it) you access next element of array
here is good example for better understanding
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
return 0;
}
this will output:
10, 20, 30, 40, 50,

Adding to the location of a pointer in C++

I have int foo which has the address of an integer in it.
How do I add to the integer that foo is pointing to in one line?
Solution:
(*(int *)foo)+=1
This is how I handled it.
To add to the value the pointer is pointing to:
int * pointer;
int value;
(*pointer) += value; // parans for clarity, not necessarily needed
int a = 4;
int* foo = &a;
// and now the one line you asked
*foo = *foo + 2; // a = 6
If you are incrementing by one and feel like writing it the shortest way (++*pointer). Example:
int i = 0;
int* ip = &i;
cout << i << endl;
++*ip;
cout << i << endl;
Output:
0
1

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