I'm having trouble with c++ pointers. I have a pointer to array of pointers.
and the case is:
MyType *(*arr)[5];
MyType **a = arr;
the 2nd line gives an error. How can i take pointer to this array ?
The error says it all (include it in your question the next time).
You declare a pointer to array of five pointers to MyType. Then you try to assign it to pointer-to-pointer-to MyType. This is exactly what error message says:
IntelliSense: a value of type "MyType *(*)[5]" cannot be used to initialize an entity of type "int **"
Another suggestion is to tell, what you are trying to achieve. Though my explanation is technically correct, I doubt it will solve your actual problem.
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
Here arr is a pointer which points to an array of pointers. So if you want to take pointer to the array, use MyType **a=*(arr+i) where *(arr+i) is the i th array.
Related
I have a variable definition int (**ff)[4];, which is very bad looking. If I'm right (inferred from the fact that int (*f)[4]; is a pointer to an array of 4 int-s) this is a pointer to a pointer to an array of 4 int-s.
Now I have tried to initialize this thing but I had no success. Initializing f was simple (f = new int[5][4];), but the line ff = new int*[6][4]; is not working. Microsoft Visual Studio Community 2013 says in an error message that
a value of type "int *(*)[4]" cannot be assigned to an entity of type "int (**)[4]"
I have a very bad feeling that I really misunderstood something.
EDIT:
Sorry, that I didn't said it explicitly: What I wanted, is to allocate memory space for not only one, but for more pointers which later can point to an array of an array of 4 int-s. Of course I wanted this in one line without the help of any other definition, conversion etc.
I can (not) see this used only in this way:
int (*a)[4] = new int[6][4];
int (**ff)[4] = &a;
int (**ff)[4] means "a pointer to pointer to an array of four ints". This means we have to have int (*)[4] first - an lvalue, so we can take its address with operator&.
On the other hand, new int*[6][4]; allocates an array of pointers to an array of four pointers (the "outer" array decays). This is completely different type from the first one.
I had to help myself with cdecl.org on this one.
Edit:
I've just made this:
using PTR = int (*)[4];
int (**ff)[4] = new PTR; // hooray, a dynamically allocated pointer!
but can't figure a way without the type alias...
Actually, there is one: int (**ff)[4] = new (int (*)[4]), gathered from this Q&A. Don't forget that all you have now is a dynamically allocated uninitialized pointer.
A double pointer is a pointer to a pointer to get the obvious out of the way. That means that it will hold the memory address of a pointer, again obvious. That means you initialise your pointer and only then point your double pointer to it. Such as,
int* f[] = new int[4];
int** ff = &f;
Then to access this you can do,
(*ff)[1]
This will allow you to access the information stored in the dynamic array.
NOTE: leave the [] beside f empty if the size is not known at compile time which is the reason you should be doing it this way in the first place.
If you want to access elements of an array a[3][3] by pointer to pointer to array than you can do that by below code :
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int (*p)[3]=a;
int (**ff)[3]=&p;
To print it :
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%d ",ff[0][i][j]);
}
printf("\n");
}
Alan,
I think the problem here is your initial assumption is incorrect.
*f[4] (or (*f)[4])
would actually be an array of 4 pointers to int, not a pointer to an
array of 4 ints. Then,
**ff[4]
would be a pointer to an array of 4 pointers to
int. I would recommend backing up a little, with this information in hand, and
trying it again. Also, an assignment to the
**ff
would be a single pointer, and
probably not an array, depending on how you are intending to use it.
Blake Mitchell
retired free lance programmer
Suppose we have that the following 2-dimensional array:
int multi[3][3];
As I understand it, we can then say that multi is a "pointer to a pointer", or -- at the very least -- we can do something like the followiong:
int **p_p_int = multi;
Question: Why don't we say that multi is a "pointer to a pointer to a pointer to pointer", since multi points towards the address of its first element, which itself points to a pointer, which points towards the address of multi[0][0], which itself points to the value of multi[0][0].
This seems to be 4 objects that point (here I'm counting addresses as pointers).
Now you might say "but addresses aren't pointers, even though pointers can equal addresses", in which case it also seems weird to say that a 2-dimensional array is a "pointer to a pointer", since it's actually a pointer to an address to a pointer to an address (to a value).
I feel like I have mananaged to confuse myself quite a bit here :)
A 1d array converts to a pointer rather than being one — e.g. you can reassign a pointer, you cannot reassign an array.
A literal 2d array isn't stored in the way described below.
However a 2d array can be achieved by a pointer to a pointer if:
int **array2d is a pointer. It points to an array. That array contains pointers.
Because array2d points to an array of pointers, array2d[n] is also a pointer. But it's a pointer to an array of integers.
So that's two pointers, total.
In pseudo code, the steps to look up the item at (m, n) are:
add m to array2d to index that array. Read pointer, p from calculated address;
add n to p to index that array. Read integer from calculated address.
The job of a pointer is to point towards something. Just because something is both a pointer and points to something else doesn't make it a pointer to a pointer, unless that something else is a pointer.
So let's break this down:
multi points towards the address of its first element,
That makes it a pointer
which itself points to a pointer,
That makes it a pointer to a pointer.
which points towards the address of multi[0][0],
No. It contains the address of multi[0][0], it doesn't point to it.
which itself points to the value of multi[0][0]
Well, of course. It's a pointer, pointers point to values, that's their job. That doesn't make them pointers to pointers, it makes them pointers to values.
This seems to be 4 objects that point (here I'm counting addresses as pointers).
Sure, but two of those pointings are the very same pointing just counted twice. You say X is a pointer that contains a value that points to something as if that was two separate pointings. The job of a pointer is to have a value that points to something, that's what makes it a pointer in the first place. It's two ways of saying the same thing, "X is a pointer" = "X contains a value (of a type) that points to something".
Saying that multi is a pointer to a pointer is just wrong. It is a 2D array.
multi can not be converted to a ** - only to *
A pointer to pointer would obviously point to a pointer. multi is not doing that. You'll find an integer at that location - not a pointer - simply because multi is not an array of pointers. multi[n] may also be converted to a * but the converted value is not taken from a place where it was stored - it is just calculated from multi.
Don't think of a 2D array like:
int a[3];
int b[3];
int c[3];
int* x[3] = {a, b, c};
cause that is simply not how 2D arrays work.
All pointer values you get from a 2D array are calculated values - not stored values.
I think that there are two unrelated stuff here that you are mixing up:
the name of any array of the type T[][][]...n...[] decayes into T*[][][]...n-1...[] for example:
int arr [7] decayes into int* arr
std::fstream arr[2][2] decays into std::fstream* arr[2]
by decaying, we mean that a function which can get T can also accept T' which T' is the decayed type of T
you can dynamically create psuedo 2 dimentional arrays by using pointer to pointer and dynamic allcoation
int** psuedeo2DimArray = new int*[10];
for (auto i=0U;i<10;i++){
psuedeo2DimArray[i] = new int[10];
}
In all cases, the type of multi is int[2][2] and nothing else.
What is the array of pointer to the structure?
is it something like this:
StructureName objectname[size];
int *ptr;
ptr=objectname;
Please confirm me with this.
This is the array of pointers to some structure:
StructureName* objectname[size];
// ^
which is the closest thing I can think of when you refer to:
array of pointer to the structure
I'm assuming you meant ptr to be a StructureName*, otherwise your code won't compile.
No, that is not an array of pointers to a struct. What you have done is used array-to-pointer to conversion to assign the array objectname to ptr. This makes ptr a pointer to the first element of the array.
An array of pointers to struct is something like:
StructureName* objectname[size];
Here, we are declaring an array objectname that has size pointers to StructureNames. The elements of the array are pointers. This makes it an array of pointers.
On the other hand, your title asks about a pointer to an array of structs, in which case it would look like this:
StructureName (*objectName)[size];
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is array name a pointer in C?
char arr[1024];
arr++ //move arr to arr+1, error!
I have heard the the name of a char array is a char pointer, is it?
The name of an array decays to an pointer to its first element sometimes.
An expression with array type will convert to a pointer anytime an array type is not legal, but a pointer type is.
You cannot do:
arr++;
Because array is an non modifiable l-value.
An array is a block of memory to which you gave a name.
What does it mean to "increment" it by one? That doesn't make any sense.
A pointer is a memory address. "Incrementing" it by one means to make it point to the element after it.
Hope that makes sense.
Arrays and pointers are not always exchangeable. A more interesting example to illustrate the difference between arrays and pointers is a 2D array:
Consider int **a and int b[3][3].
In the first approach to a 2D array we have a 1D array of pointers to 1D arrays in memory (of course you have to allocate the memory dynamically to use this).
In the second approach of actually using a 2D C array, we have the elements laid out sequentially in memory, and there's no separate location where an array of pointers are stored.
If you try to dereference b, you get a pointer to its first element (i.e. b gets converted to an int (*)[3] type).
nothing, apart from looks..
Well and as you defined the array there you declared already 1024 bytes for the array. Also you obviously can't change the array "base".
An array name is for most (but not all) purposes identical to a constant pointer (not to be confused with a pointer to a constant). Because it's a constant, you cannot modify it with the increment operator ++. There's a good answer explaining this in more detail in an older similar question.
I know this might be a common question but I have tried to search but still cannot find a clear answer.
I have the following code:
int* f() {
int a[] = {1,2,3};
return a;
}
int main() {
int a[] = f(); // Error here
getch();
return 0;
}
This code produces the error message: "Cannot convert from 'int *' to 'int []'"
I found this quite strange because I have read that pointer and array are similar. For example, we can use a[i] instead of *(a + i).
Can anyone give me a clear explanation, please?
There are actually two errors in this code.
Firstly, you are returning the address of a temporary (the int array within f), so its contents are undefined after the function returns. Any attempt to access the memory pointed to by the returned pointer will cause undefined behaviour.
Secondly, there is no implicit conversion from pointers to array types in C++. They are similar, but not identical. Arrays can decay to pointers, but it doesn't work the other way round as information is lost on the way - a pointer just represents a memory address, while an array represents the address of a continuous region, typically with a particular size. Also you can't assign to arrays.
For example, we can use a[i] instead of *(a + i)
This, however, has little to do with the differences between arrays and pointers, it's just a syntactic rule for pointer types. As arrays decay to pointers, it works for arrays as well.
The type int[] doesn't actually exist.
When you define and initialize an array like
int a[] = {1,2,3};
the compiler counts the elements in the initializer and creates an array of the right size; in that case, it magically becomes:
int a[3] = {1,2,3};
int[] used as a parameter to a function, instead, it's just plain int *, i.e. a pointer to the first element of the array. No other information is carried with it, in particular nothing about the size is preserved. The same holds when you return a pointer
Notice that an array is not a pointer: a pointer can be changed to point to other stuff, while an array refers always to the same memory; a pointer does not know anything about how big is the space of memory it points to, while the size of an array is always known at compile time. The confusion arises from the fact that an array decays to a pointer to its first element in many circumstances, and passing it to a function/returning it from a function are some of these circumstances.
So, why doesn't your code work? There are two big errors:
You are trying to initialize an array with a pointer. We said that an int * doesn't carry any information about the size of the array. It's just a pointer to the first element. So the compiler cannot know how big a should be made to accomodate the stuff returned by f().
In f you are returning a pointer to a variable that is local to that function. This is wrong, because a pointer does not actually store the data, it only points to where the data is stored, i.e. in your case to the a local to f. Because that array is local to the function, it ceases to exist when the function exits (i.e. at the return).
This means that the pointer you are returning points to stuff that does not exist anymore; consider the code:
int * a = f();
This initialization works, and you can try to use a later in the function, but a will be pointing to the no-longer existent array of f; in the best case your program will crash (and you'll notice immediately that you've done something wrong), in the worst it will seem to work for some time, and then start giving strange results.
int * and int [] are similar but different.
int * is a real pointer, meanwhile int[] is an array reference ( a sort of "constant pointer" to the begin of the data) wich cannot be modified. So, a int * can be threated like a int [] but not viceversa.
You can use a[b] and*(a+b) interchangeably because that is exactly how a[b] is defined when one of a or b is a pointer and the other is of integer or enumeration type.
Note: This also means that expressions like 42[a] are perfectly legal. Human readers might object strongly, but the compiler won't bat an eye at this.