Pointing to a reference in C++ - c++

So I am trying to understand pointers and references.
Lets say we have the following:
int val = 100;
int *ip = &val;
Why is that not the same as simply pointing to val like this:
int val = 100;
int *ip = val;

Neither one of your two examples contains a pointer to reference:
The first example has a pointer to int, properly initialized using the address-of operator &
The second example has a pointer to int, improperly initialized to the value of val itself
Generally, you do not assign values to pointers directly: normally, you want an address-of operator, an implicit pointer conversion, or some pointer arithmetic. Although assigning a well-known address on specific hardware is also possible, compiler toolchains often provide ways to keep this outside of your program. Hence, if you see an assignment int *ip = 100 it's almost certainly incorrect.
If you want a reference, declare it like this:
int val = 100;
int &ref = val;
Now you can make a pointer to that reference, like this:
int *ipRef = &ref;
Since ref represents an alias for val, ipRef would have the same value as ip from your example (demo).

Easy way to understand why they are not the-same if you do this your self.
int val = 100;
cout<<val<<endl;
You shoud get 100 as output.
Now try:
int val = 100;
cout<<&val<<endl;
You should get a 0x7ffc201cab0c or something similar as the outout.
If you access val with the "&", you are accessing the memory address of it.
If you access val without the "&", you are accessing the value of it.
Therefore if you do
int val = 100;
int *ip = val;
you will should get a warning or an error but assuming that you want to see it compile so you can figure out what would happen, this is what it you should do:
int val = 100;
int *ip;
*ip = val;
This is the-same as the previous code except that it will compile. You are creating a pointer and assigning a value to the pointer instead of assigning a memory address to it. The code is valid but has a run-time error. The pointer ip is NOT pointing anywhere before you assigned value to it.
To make it work properly, you can do:
int val = 100;
int *ip = new int;
*ip = val;
Now, you have a pointer with a memory address. The value of that pointer is val which is 100. That's the value NOT the memory address.
To conclude this, pointer must be initialized or it will have undefined behavior or even crash. You use the ref sign (&) or the new keyword to initialize pointers then you can assign assign values to it.
int val = 100;
int *ip = new int; //Create a new pointer and initilize it with a new memory address
*ip = val; //Assign the value from val(100) to the pointer
OR
int val = 100;
int *ip = &val; //Create a new pointer and initialize it by making it point to existing address of **val**
*ip = 200; //change the value in the **memory addresss to **200**
Now val changes to 200 too.
int otherValue = 500;
*ip = otherValue ; //change the value in the **memory address** to 500
Now val changes to 500 too.
CHANGE MEMORY ADDRESS WHERE ip IS POINTING
You can also change the memory address anytime.
Lets make p point to otherValue.
*ip = &otherValue; //Point p to otherValue memory address not value
*ip = 5; //Change the value of p to 5(no memory address change)
Now otherValue has 5 as the value. p points to otherValue memory address.

val is an integer, so you can not assign an int to a pointer that points to an int because is not the valid value, you will need the address (obtained with the & operator)

Because pointers and integers are different data types.
int *ip = &val;
This initialises one int* with another int* (the value obtained by taking the address of val).
int *ip = val;
This is an attempt to initialise an int* with an int, which is not allowed.
Note that your code examples do not contain any references.

Related

*pt = x; not working (meaning of * and & in C++)

I am totally newbie and have hard time digesting pointer section in C++.
What I have understood is this:
to access the content of the address, use *
to access the address of the content, use &
So basically my question is this: why is the codes below throw errors?
int x = 10;
int *pt;
*pt = x;
Why should I code in formats like the below?
int x = 10;
int *pt;
pt = &x;
Also I can't understand *pt = &x; line. *pt should be the content, not the address. Why is it ok?
int x = 10;
int *pt = &x;
Similarly, to make temp share the same address with n1, I think it should be
int n1 = 1;
int &temp = &n1;
but textbook says right code is below.
int n1 = 1;
int &temp = n1;
Need HELP!
You are confusing the meaning of * and & in the expression with their meaning in variable type declaration. In variable type * just means that this variable is a pointer, while & means that it is a reference, e.g.:
int *pt = &x;
actually means "declare a pointer to int with name pt and assign the address of x to it". While
int &temp = n1;
means "declare a reference to int named temp and assign n1 to it, so that temp refers to the same memory as n1".
I think you are confusing about mean of '&' and '*'.
In a nutshell,
&x: A bowl of x address.
*pt: A fork for choose address(only address).
And if you declare as 'int *pt', you don't need to declare as '*pt=&x'. Because 'pt' is already pointer variable.
Pointer is a "reference to memory for particular type". In example you wrote int *pt; Instead try to think about it like:
int x = 10;
// Declare a pointer to location in memory.
// That memory is holding (or will be) value of type int.
int* pt;
// What would be be the meaning of this? *pt doesn't really mean anything.
// int* means that it is points to type of integer
*pt = x;
Similar approach is for the &x, which is only shortcut for:
"I know that there is variable x of type int and I would like to get address (of first byte of that int)".
// Again from the example, you declare int x to value 10.
int x = 10;
// Declare pointer for int type.
int* pt;
// Set pointer (variable that specifies the location in memory)
// to address of variable x (so you point "pointer pt" to location in memory
// where variable x sits
pt = &x;
Finally if you connect the dots:
int x = 10;
// 1st declare pointer of type int
// point the pointer to the value x
int* pt = &x;
why is the codes below throw errors?
1> int x = 10;
2> int *pt;
3> *pt = x;
*pt in line 3 accesses the int pointed to by pt, but at this time the value of pt is undefined.
Why should I code in formats like the below?
int x = 10;
int *pt;
pt = &x;
Assign a pointer that points to x to pt, so now the pointer pt points to x.
Also i can't understand *pt = &x; line. *pt should be the content, not
the address. Why is it ok?
int x = 10;
int *pt = &x;
No, pt is a variable and int * is its type. This code has the same meaning as the previous one.
Similarly, to make temp share the same address with n1, i think it
should be
int n1 = 1;
int &temp = &n1;
but textbook says right code is below.
int n1 = 1;
int &temp = n1;
int & is a C++ reference type, it is not a pointer, so the & operator is not needed to get the address of n1. At this time pt is already binded to n1.

array pointers in c++

How do you access/dereference with arrays in c++??
for example, if I have this code
int num[] = {0,1,2,3};
int *p = &num;
I thought p was point to the first element in num array?
For some reason, I get a compiler error.
I want to use pointers and increments to access and change the value that is pointing,
for example, p gets the address of the first variable in the int array num and if I increment p, I get the address of the second variable in the int array num.
Any tips would be appreciate it.
I thought p was point to the first element in num array?
No. int *p = &num; is wrong, since &num is not a pointer to an int, i.e. int*, but is actually a pointer to an array of ints, i.e. int (*) [4].
To get a pointer to the first element, you can use int *p = num;, or int *p = &num[0]; instead.

Why pointer to pointer?

A very general question: I was wondering why we use pointer to pointer?
A pointer to pointer will hold the address of a pointer which in turn will point to another pointer. But, this could be achieved even by using a single pointer.
Consider the following example:
{
int number = 10;
int *a = NULL;
a = &number;
int *b = a;
int *pointer1 = NULL;
pointer1 = b; //pointer1 points to the address of number which has value 10
int **pointer2 = NULL;
pointer2 = &b; //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??
return 0;
}
I think you answered your own question, the code is correct, what you commented isn't.
int number = 10; is the value
int *pointer1 = b; points to the address where int number is kept
int **pointer2 = &b; points to the address where address of int number is kept
Do you see the pattern here??
address = * (single indirection)
address of address = ** (double indirection)
The following expressions are true:
*pointer2 == b
**pointer2 == 10
The following is not!
*pointer2 == 10
Pointer to pointer can be useful when you want to change to what a pointer points to outside of a function. For example
void func(int** ptr)
{
*ptr = new int;
**ptr = 1337;
}
int main()
{
int* p = NULL;
func(&p);
std::cout << *p << std::endl; // writes 1337 to console
delete p;
}
A stupid example to show what can be achieved :) With just a pointer this can not be done.
First of all, a pointer doesn't point to a value. It point to a memory location (that is it contains a memory address) which in turn contains a value. So when you write
pointer1 = b;
pointer1 points to the same memory location as b which is the variable number. Now after that is you execute
pointer2 = &b;
Then pointer2 point to the memory location of b which doesn't contains 10 but the address of the variable number
Your assumption is incorrect. pointer2 does not point to the value 10, but to the (address of the) pointer b. Dereferencing pointer2 with the * operator produces an int *, not an int.
You need pointers to pointers for the same reasons you need pointers in the first place: to implement pass-by-reference parameters in function calls, to effect sharing of data between data structures, and so on.
In c such construction made sense, with bigger data structures. The OOP in C, because of lack of possibility to implement methods withing structures, the methods had c++ this parameter passed explicitly. Also some structures were defined by a pointer to one specially selected element, which was held in the scope global to the methods.
So when you wanted to pass whole stucture, E.g. a tree, and needed to change the root, or 1st element of a list, you passes a pointer-to-a-pointer to this special root/head element, so you could change it.
Note: This is c-style implementation using c++ syntax for convienience.
void add_element_to_list(List** list, Data element){
Data new_el = new Data(element); // this would be malloc and struct copy
*list = new_el; //move the address of list, so it begins at new element
}
In c++ there is reference mechanismm and you generally you can implement nearly anything with it. It basically makes usage of pointers at all obsolete it c++, at least in many, many cases. You also design objects and work on them, and everything is hidden under the hood those two.
There was also a nice question lately "Why do we use pointers in c++?" or something like that.
A simple example is an implementation of a matrix (it's an example, it's not the best way to implement matrices in C++).
int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
M[i] = new double[ncols];
M[3][7] = 3.1416;
You'll rarely see this construct in normal C++ code, since C++ has references. It's useful in C for "passing by reference:"
int allocate_something(void **p)
{
*p = malloc(whatever);
if (*p)
return 1;
else
return 0;
}
The equivalent C++ code would use void *&p for the parameter.
Still, you could imagine e.g. a resource monitor like this:
struct Resource;
struct Holder
{
Resource *res;
};
struct Monitor
{
Resource **res;
void monitor(const Holder &h) { res = &h.res; }
Resource& getResource() const { return **res; }
}
Yes, it's contrived, but the idea's there - it will keep a pointer to the pointer stored in a holder, and correctly return that resource even when the holder's res pointer changes.
Of course, it's a dangling dereference waiting to happen - normally, you'd avoid code like this.

Pointers problem

I have a question.
I created a correctly initialized integer pointer
int * p
and a correctly initialized integer array
int * array1 = new int[]
Which of the following is legal code?
p = array1;
array1 = p;
Or are both correct?
is this possible as well
p[0] since, to my pointer arithmetic knowledge, it doesn't add anything.
All in c++
If the question is trying to get at pointers versus arrays, they are not always compatible. This is hidden in the presented code because the array is immediately converted to a pointer.
int* array1 = new int[5]; // Legal, initialising pointer with heap allocated array
int array2[5] = {0}; // Declaring array directly on the stack and initalising with zeros
int *p = 0; // Declaring pointer and initialising to numm
p = array2; // Legal, assigning array to pointer
p = array1; // Legal, assigning pointer to pointer
array1 = p; // Legal, assigning pointer to pointer
array2 = p; // ILLEGAL, assigning pointer to array
Here array2 has an array type and cannot be used to store a pointer. Actually, the array cannot be reassigned at all, as it is not an l-value.
int array3[5] = {0}; // Declaring array directly on the stack and initalising with zeroes
array3 = array2; // ILLEGAL, array not an l-value
The array has a fixed address and reassiging it would be similar to trying to write:
int i = 0;
&i = p;
[Hopefully, trying to reassign the location of a variable is obvious nonsense.]
Both are legal.
The first, "p = array1", will cause your correctly initialized integer pointer to be leaked and to point p to the first occurrence of the array that array1 points to.
The second, "array1 = p", will cause the correctly initialized integer array to to be leaked and to point array1 to the single int that p points to.
So I suspect I'm missing something. Could you perhaps post complete code?
If both p and array1 are declared as "int *", as you imply here, then either assignment is legal, by definition.
both are leagal.
passing adresses to eachother. dont knw what u want to do
According to the explanation provided in this site. The first assigned in is correct but the second assignment cannot be considered valid. Please look under the title 'Pointers and arrays'.
You can assign your array variable to pointer variable. So p = array1 is correct.
You can refer this code.
#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] << ", ";
for (int n=0; n<5; n++)
cout << p[n] << ", ";
return 0;
}
If both are pointers then no need to declare pointer as array like int *array1 = new int[].
Both variables are of type pointer to int. So both assignments are legal. The fact that one of the variables is an array doesn't matter in C. Arrays and pointers are the same after initialization.
"I created a correctly initialized integer pointer int * p and a correctly initialized integer array int * array1 = new int[]"
First of all, keeping the syntactical mistakes aside, the terminology is wrong.
int *p; - Here you are just declaring a pointer to hold an integer variable's address. You are not initializing it. Declaration is different from initialization and initialization is different from assignment.
int *array1 = new int[]; - Keeping the error aside, this is not an initialized integer array. array1 is a pointer pointing to an array of integers.
And passing nothing to [] is incorrect. A value needs to be passed that decides number of memory locations to be allocated for holding integer values.
Answering the questions.
Which of the following is legal code?
p = array1;
If, array1 is properly initialized it's correct. p points to the first integer in the array1. Even if it is not properly initialized also, it is correct. In this case, both array and p points to garbage values.
int* array1 = new int[5]; // Notice **5** being passed.
array1 = p;
Infact this operation is useless. Both p and array1 were both pointing to the same location earlier. But this is legally correct.
is this possible as well p[0] ?
Yes, it's correct. p can dereference to 0 to 4 as it's index values. If you just want to p[0], in that case -
int* array1 = new int ; // Notice nothing being passed.

Initializing pointers in C++

Can assign a pointer to a value on declaration? Something like this:
int * p = &(1000)
Yes, you can initialize pointers to a value on declaration, however you can't do:
int *p = &(1000);
& is the address of operator and you can't apply that to a constant (although if you could, that would be interesting). Try using another variable:
int foo = 1000;
int *p = &foo;
or type-casting:
int *p = (int *)(1000); // or reinterpret_cast<>/static_cast<>/etc
What about:
// Creates a pointer p to an integer initialized with value 1000.
int * p = new int(1000);
Tested and works. ;-)
There are two things not clear in the question to me. Do you want to set the pointer to a specific value (i.e address), or do you want to make the pointer point to some specific variable?
In the latter case, you can just use the address-of operator. The value of the pointer is then set to the address of some_int_variable.
int *p = &some_int_variable;
*p = 10; // same as some_int_variable = 10;
Note: What follows is evil changing of the pointer's value manually. If you don't know whether you want to do that, you don't want to do it.
In the former case (i.e setting to some specific, given address), you can't just do
int *p = 1000;
Since the compiler won't take the int and interpret it as an address. You will have to tell the compiler it should do that explicitly:
int *p = reinterpret_cast<int*>(1000);
Now, the pointer will reference some integer (hopefully) at address 1000. Note that the result is implementation defined. But nevertheless, that are the semantics and that is the way you tell the compiler about it.
Update: The committee fixed the weird behavior of reinterpret_cast<T*>(0) that was suggested by a note and for which i provided a workaround before. See here.
Um. I don't think you can take a non-const address of a constant like that.
but this works:
int x = 3;
int *px = &x;
cout << *px; // prints 3
or this:
const int x = 3;
const int *px = &x;
const int *pfoo = reinterpret_cast<const int*>(47);