###### Asked By: Anonymous

I am trying to declare a 2D array, where each element in the inner array has type `uint64_t*`

. I want to do this in a single line using `new`

, which should be possible in C++11 or later. I tried this:

```
uint64_t ***db = new uint64_t*[2][64];
```

However, this is incorrect:

```
cannot initialize a variable of type 'uint64_t ***' (aka 'unsigned long long ***') with an rvalue of type 'uint64_t *(*)[64]'
```

Note that the code works correctly when I replace the type with `auto`

.

What is the correct type for the variable?

## Solution

###### Answered By: Anonymous

If you want a pointer to an array on heap, you use a pointer to the first element. This means it’s the same type as if you would allocate a single element:

```
uint64_t* p1 = new uint64_t;
uint64_t* p2 = new uint64_t[2];
```

You should one the second line only use `p`

and `p+1`

, because `p+2`

is in this example out of range. This goes for all examples below WITH BRACKETS as well.

If you create a pointer to a multidimensional array, you also use a pointer to the first element, but the notation slightly changes. You don’t always need the parentheses, but I left them in to see the patterns clearly:

```
uint64_t (*p1) = new uint64_t; // Optional parentheses.
uint64_t (*p2) = new uint64_t[2]; // Optional parentheses.
uint64_t (*p3)[3] = new uint64_t[2][3]; // Required parentheses.
uint64_t (*p4)[3][4] = new uint64_t[2][3][4]; // Required parentheses.
```

As you can see, we need parentheses when there are brackets.

And now with pointers:

```
uint64_t *(*p1) = new uint64_t*; // Optional parentheses.
uint64_t *(*p2) = new uint64_t*[2]; // Optional parentheses.
uint64_t *(*p3)[3] = new uint64_t*[2][3]; // Required parentheses.
uint64_t *(*p4)[3][4] = new uint64_t*[2][3][4]; // Required parentheses.
```

And finally, BONUS round:

```
uint64_t **(*p1) = new uint64_t**; // You can leave out the parentheses.
uint64_t **(*p2) = new uint64_t**[2]; // You can leave out the parentheses.
uint64_t **(*p3)[3] = new uint64_t**[2][3];
uint64_t **(*p4)[3][4] = new uint64_t**[2][3][4];
```