Reference to a derefrenced pointer - c++

Is the following standards compliant c++ code?
int *p;
p = new int;
int &n = *p;
n = 5;
Furthermore, am I right in thinking that this code would essentially allocate memory for an int, then give a name, specifically n, to that memory location that could be used like a normal int type variable?

The given code
int *p;
p = new int;
int &n = *p;
n = 5;
is valid.
I'd write just “yep” as an answer but SO rules – and the sometimes very rule-based users – won't admit such a brief answer.

Related

What is the difference between int* p and int** p in c++? [duplicate]

What is the difference between int* i and int** i?
Pointer to an integer value
int* i
Pointer to a pointer to an integer value
int** i
(Ie, in the second case you will require two dereferrences to access the integer's value)
int* i : i is a pointer to a object of type int
int** i : i is a pointer to a pointer to a object of type int
int*** i : i is a pointer to a pointer to a pointer to object of type int
int**** i : i is a pointer to a pointer to a pointer to a pointer to object of type int
...
int* pi
pi is a pointer to an integer
int **ppi
ppi is a pointer to a pointer to an integer.
EDIT :
You need to read a good book on pointers. I recommend Pointers on C by Kenneth Reek.
Let's say you're a teacher and have to give notes to one of your students.
int note;
Well ... I meant the whole class
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
Well ... don't forget you have several classes
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
And, you also teach at several institutions
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
etc, etc ...
I don't think this is specific to opencv.
int *i is declaring a pointer to an int. So i stores a memory address, and C is expecting the contents of that memory address to contain an int.
int **i is declaring a pointer to... a pointer. To an int. So i contains an address, and at that memory address, C is expecting to see another pointer. That second memory address, then, is expected to hold an int.
Do note that, while you are declaring a pointer to an int, the actual int is not allocated. So it is valid to say int *i = 23, which is saying "I have a variable and I want it to point to memory address 23 which will contain an int." But if you tried to actually read or write to memory address 23, you would probably segfault, since your program doesn't "own" that chunk of RAM. *i = 100 would segfault. (The solution is to use malloc(). Or you can make it point to an existing variable, as in int j = 5; int *i = &j)
Imagine you have a few friends, one of them has to give you something (a treasure... :-)
Say john has the treasure
int treasure = 10000; // in USD, EUR or even better, in SO rep points
If you ask directly john
int john = treasure;
int you = john;
If you cannot join john, but gill knows how to contact him,
int john = treasure;
int *gill = &john;
int you = *gill;
If you cannot even join gill, but have to contact first jake who can contact gill
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
Etc... Pointers are only indirections.
That was my last story for today before going to bed :-)
I deeply believe that a picture is worth a thousand words. Take the following example
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
So in the above, A points to the first integer in the sequence of N integers. And P points to a pointer that the caller will have the pointer to the found integer stored in.
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P is used to pass the address of P to the function. This address has type int **, because it's the address of a pointer to int.
int* i is the address of a memory location of an integer
int** is the address of a memory location of an address of a memory location of an integer
int* i; // i is a pointer to integer. It can hold the address of a integer variable.
int** i; // i is a pointer to pointer to integer. It can hold address of a integer pointer variable.
Neither is a declaration. Declaration syntax does not allow () around the entire declaration. What are these () doing there? If this is supposed to be a part of function declaration, include the whole function declaration thing in your question, since in general case the actual meaning of a declaration might depend on that. (Not in this one though.)
As for the difference... There is one * in the first and there are two *s in the second. Does it help? Probably not. The first one declares ias a pointer to int. The second one declares i as a pointer to int *. Does this help? Probably not much either. Without a more specific question, it is hard to provide a more meaningful answer.
Provide more context, please. Or, if this is actually as specific as it can get, read your favorite C or C++ book about pointers. Such broad generic questions is not something you ask on the net.
Note that
int *i
is not fully interchangeable with
int i[]
This can be seen in that the following will compile:
int *i = new int[5];
while this will not:
int i[] = new int[5];
For the second, you have to give it a constructor list:
int i[] = {5,2,1,6,3};
You also get some checking with the [] form:
int *i = new int[5];
int *j = &(i[1]);
delete j;
compiles warning free, while:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
will give the warnings:
warning C4156: deletion of an array expression without using the array form of 'delete'; array form substituted
warning C4154: deletion of an array expression; conversion to pointer supplied
Both of these last two examples will crash the application, but the second version (using the [] declaration type) will give a warning that you're shooting yourself in the foot.
(Win32 console C++ project, Visual studio 2010)
Textual substitution is useful here, but beware of using it blindly as it can mislead you (as in the advanced example below).
T var; // var has type T
T* var; // var has type "pointer to T"
This works no matter what T is:
int* var; // pointer to int
char* var; // pointer to char
double* var; // pointer to double
// advanced (and not pure textual substitution):
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints"
// also known as "int[3]"
int3* var; // pointer to "array (of size 3) of ints"
// aka "pointer to int[3]"
int (*var)[3]; // same as above, note how the array type from the typedef
// gets "unwrapped" around the declaration, using parens
// because [] has higher precedence than *
// ("int* var[3];" is an array (size 3) of pointers to int)
This works when T is itself a pointer type:
typedef int* T; // T is a synonym for "pointer to int"
T* var; // pointer to T
// which means pointer to pointer to int
// same as:
int** var;

*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.

Pointing to a reference in 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.

How *restrict / *__restrict__ works in C / C++?

Here is some code I wrote (using GCC's __restrict__ extension to C++):
#include <iostream>
using namespace std;
int main(void) {
int i = 7;
int *__restrict__ a = &i;
*a = 5;
int *b = &i, *c = &i;
*b = 8;
*c = 9;
cout << **&a << endl; // *a - which prints 9 in this case
return 0;
}
Or, the C version (in case the C++ version is not clear due to the use of an extension which every popular C++ compiler supports), using GCC:
#include <stdio.h>
int main(void) {
int i = 7;
int *restrict a = &i;
*a = 5;
int *b = &i, *c = &i;
*b = 8;
*c = 9;
printf("%d \n", **&a); // *a - which prints 9 in this case
return 0;
}
From what I've read, if I do *a = 5, it changes the value of the memory he, a, is pointing to; after that, the memory to which he is pointing to should not be modified by anyone else except a, which means that these programs are wrong because b and c modify it after that.
Or, even if b modifies i first, after that only a should have access to that memory (i).
Am I getting it correctly?
P.S: Restrict in this program doesn't change anything. With or without restrict, the compiler will produce the same assembly code. I wrote this program just to clarify things, it is not a good example of restrict usage. A good example of restrict usage you can see here: http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
No.
Statements
*b = 8;
*c = 9;
will cause undefined behavior.
From documentation:
A pointer is the address of a location in memory. More than one pointer can access the same chunk of memory and modify it during the course of a program. The restrict type qualifier is an indication to the compiler that, if the memory addressed by the restrict-qualified pointer is modified, no other pointer will access that same memory. The compiler may choose to optimize code involving restrict-qualified pointers in a way that might otherwise result in incorrect behavior. It is the responsibility of the programmer to ensure that restrict-qualified pointers are used as they were intended to be used. Otherwise, undefined behavior may result.

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);