Question: Why is this an error:

```
typedef int H[4];

H * h = new H;        // error: cannot convert 'int*' to 'int (*)[4]' in initialization

```

?

Furthermore, why is this *not* an error:

```
H * h = new H[1];

```

?

Why does the compiler consider that `new H` returns an `int *`, whereas `new H[1]` returns an `H *` as expected ?

To put it another way: **why is it that `T * t = new T;` is correct for a general type T, but is not correct when `T` is an array type ?**

What would be the canonical way to allocate a simple array type such as this via `new` ?

Note that this is a simplified example, so e.g. `new int[4]` is not an acceptable workaround - I need to use the actual type from the preceding `typedef`.

Note also that I'm aware that using `std::vector`, `std::array`, *et al* is generally preferable over C-style arrays, but I have a "real world" use case where I need to work with types such as the above.

Answer: 
Main Question

> 
> [What is the] Preferred method to `new` pointer to array
> 
> 
> 

Constraint: 

> 
> Note also that I'm aware that using std::vector, std::array, et al is generally preferable over C-style arrays, but I have a "real world" use case where I need to work with types such as the above.
> 
> 
> 

Answer:

for the non-array case:

```
#include <memory>

auto h = std::make_unique<H>();

// h is now a std::unique_ptr<H> which behaves to all intents and purposes
// like an H* but will safely release resources when it goes out of
// scope
// it is pointing to a default-constructed H

// access the underlying object like this:
h.get(); // yields H*
*h;      // yields H&

```

For the array case:

```
#include <memory>

auto h = std::make_unique<H[]>(4);

// h is now a std::unique_ptr<H[]> which behaves to all intents and purposes
// like an H* but will safely destruct and deallocate the array 
// when it goes out of scope
// it is pointing to an array of 4 default-constructed Hs

// access the underlying object like this:
h[1];     // yields H& - a reference to the 2nd H
h.get();  //yields H* - as if &h[0]

```
You can see why if you basically do the typedef substitution manually:

```
H * h = new H;

```

Reduces to:

```
int[4]* h = new int[4];

```

while

```
H * h = new H[1];

```

reduces to:

```
(int*)[4] h = new int[1][4];

```

Because of the array to pointer decay rules, this is legal.

If you want an actual workaround, and you know the type of H, you can do something like:

```
typedef int* J;
typedef int H[4];

J j = new H; // This will work

```