I don't quite understand where the error is here:
int *parr[22]; // Array of int* pointers
parr[0] = ptr1;
parr[1] = ptr2;
//...
int *(*pparr)[22]; // A pointer to a int* array[22]
pparr = parr; // ERROR
the error tells me error C2440: '=' : cannot convert from 'int *[22]' to 'int *(*)[22]'
how come that the types are not equal? The name of the array should be equal to a reference to the first element of the array, something like
parr => &parr[0]
so the line seems right to me
As pparr is A pointer to a int* array[22] so you need to write
pparr = &parr;
You need to store address in the pointer and not the pointer itself.
It is same like when you have
int a=3;
int *b;
b=&a;
You are storing address of a in b, similarly you need to store address of parr in pparr
EDIT: To clarify OP's comment
You can't assign the address of the first element, but the address of the pointer that is pointing to first element.(therefore pparr = &parr;)
An int*[22] can decay to an int**, but you cannot assign an int** to an int*(*)[22].
int *(*pparr)[22]; //This one is an array of function-pointers returning an int pointer.
int **pptr; //Points to an array of pointer
So you can write
pptr = parr;
Related
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;
How do you access/dereference with arrays in c++??
for example, if I have this code
int num[] = {0,1,2,3};
int *p = #
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 = # 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.
I came across this question:
In the declaration below , p is a pointer to an array of 5 int
pointers.
int *(*p)[5];
which of the following statements can be used to allocate memory for
the first dimension in order to make p an array of 3 arrays of 5
pointers to type int ?
A. p = new int [3][5]*;
B. p = new int (*)[3][5];
C. p = new int [3]*[5];
D. p = new int *[3][5];
E. p = new int (* [3] ) [5];
What is the answer ?
I am not sure I understand the question. Normally I would create a pointer to an array of 5 int as such int* p[5]; I am curious as to why they did it as int *(*p)[5];
Also what does the question want ? Is it asking to initialize (allocate memory) to the first 3 int pointers ? I would appreciate it if someone could explain this to me
F:
using IPA5 = int*[5];
IPA5 * p = new IPA5[3];
Each element p[0], p[1], p[2] is just a plain, typed array of int*. There's nothing dynamic going on beyond the initial dynamic allocation, where 3 is allowed to be a dynamic quantity.
Then p[0][i] for i in [0, 5) is an int *, which you can use in whatever way you like (which includes making it point to the first element of yet anohter dynamic array).
What you would write as:
int* p[5];
is a five element array of pointers to int.
What this declares:
int *(*p)[5];
is a pointer to a five element array of pointers to int, i.e. a pointer to the type of thing you just wrote.
In other words; you could do:
int * a[5];
int * (*p)[5] = &a;
You can mentally read this incrementally as follows:
(*p) // p is a pointer
(*p)[5] // p is a pointer to an array of size 5
int * (*p)[5] // p is a pointer to an array of size 5 of type pointer to int
You need the parentheses around *p, because otherwise:
int ** p[5];
would declare a 5 element array of type int **, or pointer to pointer to int, which is a different thing entirely.
The question is basically asking you to dynamically allocate memory equivalent to three of what a is above, so answer "D" is the correct one.
The answer is
D. p = new int *[3][5];
all the others are syntactically wrong
to realize the difference between
int * p [5];
int * (*p) [5];
consider this example
int *(*p)[5];
int pp[5];
pp[0][0] = new int [5]; //LHS is int , RHS is int ,, compilation error
p[0][0] = new int [5]; //this works because p[0][0] is a pointer not an int
try thinking about each dimension as adding you additional *
back to the question
int *(*p)[5] is giving you 3 * (***p)
so you can assign
p = int *[3][5]
because it has 3 * as well
int* p[5] has type array of size 5 of int*. It decays to int**, so p + 1 will point to the second element of that array.
int *(*p)[5] has type pointer to array of size 5 of int*. You can think of it as decayed two-dimensional array int* [][5]. So p + 1 will point to the second element of the first dimension of that array, that is to the next byte after 5 pointers to int.
Which leads us to the conclusion that the right answer is D.
(This is not to mention that other answers just don't compile regardless of type of p)
What is the answer ?
D
Normally I would create a pointer to an array of 5 int as such int* p[5]; I am curious as to why they did it as int *(*p)[5];
It is not "normally" because int* p[5] is not a pointer to an array of 5 int, it is an array of 5 pointers to int.
Also what does the question want ? Is it asking to initialize (allocate memory) to the first 3 int pointers ?
It's not clear. There is no way "to make p an array of 3 arrays of 5 pointers to type int", to begin with.
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
casting char[][] to char** causes segfault?
I have a 2D array declared like this:
int arr[2][2]={ {1,2},{3,4}};
Now if I do:
int ** ptr=(int**) arr;
and:
cout<<**ptr;
I am getting a segmentation fault (using g++-4.0).
Why so? Shouldn't it be printing the value 1 (equal to arr[0][0])?
You can't cast a linear array to a pointer-to-pointer type, since int** doesn't hold the same data int[][] does.
The first holds pointers-to-pointers-to-ints. The second holds a sequence of ints, in linear memory.
You are attempting to assign a double pointer variable to an array... this has been covered exhaustively, see here for information on this. Furthermore, since you declared
int arr[2][2] = ...;
and then try to assign arr to a double pointer
int ** ptr = ... ;
which is guaranteed to not work, hence a segmentation fault. Furthermore, that statement int ** ptr=(int**) arr; is actually cast ing one type (i.e. [][]) to another type (i.e. **) despite they are of type 'int'. They are both different and the compiler will interpret that very differently...
You could do it this way:
int *ptr = &arr;
Now *(ptr + 1) will refer to the 0'th row, *(ptr + 2) will refer to the 1'st row and so on. The only onus on you is to not overstep the markers of where arr is used otherwise an overflow can happen or even a segmentation fault...
What you do now means creating of arrays of pointers where every pointer was explicitly casted. Therefore, you would have an array of pointers like (0x00001, 0x00002, 0x00003 and 0x00004).
When dereferenced, this pointers cause your segfault.
No, int ** is a pointer to a pointer to an int, but a 2-D array is an array of arrays, and &(arr[0][0]) is a pointer to an int.
I believe you should be doing this:
int *ptr = arr;
cout<<*ptr;
or this:
int *ptr = &arr[0][0];
cout<<*ptr;
Try
int *ptr = arr;
More Explanation:
You should assign an adress to the pointer, so it can be derefenced(i mean * operator). What you do is, pointing ptr to memory cell that has the adress a[0][0]. Therefore, you get a segmentation fault.
int arr[2][2] is not an array of arrays - it is a single 2d array. In memory, it is indistinguishable from int arr[4]
What you really want is
int (*ptr)[2] = arr;