22

I have an array of int pointers int* arr[MAX]; and I want to store its address in another variable. How do I define a pointer to an array of pointers? i.e.:

int* arr[MAX];
int (what here?) val = &arr;
moteutsch
  • 3,741
  • 3
  • 29
  • 35

7 Answers7

30

The correct answer is:

int* arr[MAX];
int* (*pArr)[MAX] = &arr;

Or just:

        int* arr  [MAX];
typedef int* arr_t[MAX];

arr_t* pArr = &arr;

The last part reads as "pArr is a pointer to array of MAX elements of type pointer to int".

In C the size of array is stored in the type, not in the value. If you want this pointer to correctly handle pointer arithmetic on the arrays (in case you'd want to make a 2-D array out of those and use this pointer to iterate over it), you - often unfortunately - need to have the array size embedded in the pointer type.

Luckily, since C99 and VLAs (maybe even earlier than C99?) MAX can be specified in run-time, not compile time.

Kos
  • 70,399
  • 25
  • 169
  • 233
22

Should just be:

int* array[SIZE];
int** val = array;  

There's no need to use an address-of operator on array since arrays decay into implicit pointers on the right-hand side of the assignment operator.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • @moteustch Well, you got a pointer to the array's data, which is _almost_ the same. – Etienne de Martel May 25 '11 at 20:58
  • 5
    Yes, `val` is a pointer to the array of `int` pointers (semantically speaking) ... if you dereferenced `val`, you'll end up with your array of pointers again, i.e., you can do `(*val)[INDEX]` . So since `val` is holding the address to the start of an array of `int*`, then it's a pointer to an array of pointers. – Jason May 25 '11 at 21:01
  • 1
    @Ivella: Could you please explain? The OP asked how to define a pointer to an array of pointers, and this answer shows one way that can be done that is considered legal C-code. – Jason Jun 17 '15 at 20:33
  • 1
    @Jason `val` is not a pointer to an array of pointers. `val` is a pointer to the first pointer in the array. `(*val)[INDEX]` in not equivalent to `array[INDEX]`. Instead, `val[INDEX]` is equivalent to `array[INDEX]`. Derefrencing `val` just gives you the first pointer in the array. You haven't explained how to make a pointer to an array of pointers, but you have explained how to make a pointer the first pointer in an array. – Vaelus Jul 09 '15 at 18:16
  • Hey @Jason, do you have a reference for _"since arrays decay into implicit pointers on the right-hand side of the assignment operator"_? – Rafael Eyng Jan 13 '20 at 21:10
  • 1
    @RafaelEyng You can check out [this answer here](https://stackoverflow.com/a/1462103/649233) – Jason Jan 14 '20 at 20:01
2

IIRC, arrays are implicitly convertible to pointers, so it would be:

int ** val = arr;
Etienne de Martel
  • 34,692
  • 8
  • 91
  • 111
  • I believe that's going to throw and error in the complier for mis-matched type since `arr` is actually of type "array-of-pointers-to-int` rather than "pointer-to-int" – Jason May 25 '11 at 20:53
  • Arrays ARE convertible to pointers... But not the other way round. And also Pointers-to-arrays are not implicitly convertible to pointers-to-pointers. Et cetera, et cetera. – Kos May 25 '11 at 20:55
  • But if an array is convertible to a pointer wouldn't the original arr the same as `int** arr`? So `&arr` would be `int ***`, no? – moteutsch May 25 '11 at 20:56
  • 1
    @moteutsch: No, because `array` is considered in the C-type system to be of type "array-of-int-pointers". Written out in C, that would be of type `int* ()[]`. Now if you took the `&array`, you'd end up with the C-type `int* (*)[]` which says that `array` is a pointer to an array of `int*`. This is *NOT* the same as `int**` or any other pointer-to-pointer type. For instance, if you added a value of 1 to a type of `int* (*)[]`, you'd increment that pointer by the whole value of the array, where-as if you incremented a `int**` by 1, you'd only increment the size of a `int` pointer. – Jason May 25 '11 at 21:12
0

According to this source http://unixwiz.net/techtips/reading-cdecl.html, by using the "go right when you can, go left when you must" rule, we get the following 2 meanings of the declarations given in the previous answers -

int **val ==> val is a pointer to pointer to int
int* (*pArr)[MAX] ==> pArr is a pointer to an array of MAX length pointers to int.

I hope the above meanings make sense and if they don't, it would probably be a good idea to peruse the above mentioned source.

Now it should be clear that the second declaration is the one which moteutsch is looking for as it declares a pointer to an array of pointers.

So why does the first one also work? Remember that

int* arr[MAX]

is an array of integer pointers. So, val is a pointer to, the pointer to the first int declared inside the int pointer array.

VSarin
  • 359
  • 2
  • 5
0
#define SIZE 10
int *(*yy)[SIZE];//yy is a pointer to an array of SIZE number of int pointers
and so initialize yy to array as below -

int *y[SIZE];   //y is array of SIZE number of int pointers
yy = y;         // Initialize
//or yy = &y;   //Initialize
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. [From Review](/review/late-answers/26218458) – double-beep May 24 '20 at 17:58
  • @double-beep: There's at least _some_ explanation here—it's just not as obvious as it's handled as inline comments in the code block. I agree that providing a quick introduction would be useful here, though, and especially given that this is an old question with quite a few existing answers. – Jeremy Caney May 25 '20 at 00:49
-1

I believe the answer is simply:

int **val;
val = arr;
MM PP
  • 4,050
  • 9
  • 35
  • 61
-2

As far as I know there is no specific type "array of integers" in c, thus it's impossible to have a specific pointer to it. The only thing you can do is to use a pointer to the int: int*, but you should take into account a size of int and your array length.

dhblah
  • 9,751
  • 12
  • 56
  • 92
  • `int []` is an array of integers and it is *different* from `int *`, but will implicitly decay to `int *` when used as a function argument or in a context where pointer arithmetic is done. – dmckee --- ex-moderator kitten May 25 '11 at 20:53
  • C certainly has array types and they are not equal to pointer types, if that's what you're thinking. Try compiling `int main() { int a[1] = {0}; int i; a = &i; return 0; }` – Fred Foo May 25 '11 at 20:54
  • Most important difference between array types and pointer types is how they respond to `sizeof`. – Kos May 25 '11 at 21:02