如何使用 new 在堆上创建一个自动数组 [N]

How to create an automatic array[N] on the heap, with new

我有一个关于指针和数组的特殊情况。

如何在堆上分配固定大小(自动)的数组?让我们立即进入代码以了解我要问的问题:

typedef int ArrayOf10Ints[10];

int f()
{
        ArrayOf10Ints * p = new ArrayOf10Ints; // Error: cannot initialize a variable of type 'ArrayOf10Ints *'
                                               // (aka 'int (*)[10]') with an rvalue of type 'int *'

        ArrayOf10Ints * q = new ArrayOf10Ints[1] // OK: allocates space for 10 ints

        delete q; // Warning: use delete []
}

为什么分配 p 的表达式不起作用?为什么右值是 int* 而不是 ArrayOf10Ints*?为什么 q 有效?

注意:我的目标是了解分配 pq 的意外行为。正如其他人指出的那样,有许多直接的方法可以解决这个问题。例如,在我的例子中,我使用一个指针来表示数组是可选的——它可能存在也可能不存在——所以我会这样做:

boost::optional<std::array<int, 10> > optional_array;

Note: for reasons beyond this discussion, I need to do exactly this

当然不是,因为错误的东西是行不通的。

改用std::array<int,10>。这段代码应该可以顺利运行:

typedef array<int,10> ArrayOf10Ints;

int f() {
     ArrayOf10Ints * p = new ArrayOf10Ints;
     // ...

     delete p;
}

但是我不建议您自己管理 newdelete,除非您绝对确定自己需要这样做。

这是 new 的行为,有点令人惊讶。即使 ArrayOf10Intsint[10] 的别名,当您在 new 表达式中使用它时,结果就好像您在写 new int[10] 一样。

这是在[expr.new]/5

中指定的

When the allocated object is an array (that is, the noptr-new-declarator syntax is used or the new-type-id or type-id denotes an array type), the new-expression yields a pointer to the initial element (if any) of the array.

因此在您的示例中,new 表达式 returns 和 int *,因此出现错误。

解决方法是按照您所展示的进行操作

ArrayOf10Ints* q = new ArrayOf10Ints[1];
delete[] q;

或将数组放在 struct 中,或使用 std::array.

请注意,即使您要写

int* p = new ArrayOf10Ints;

然后您必须使用 delete[] p,因为在这种情况下也会调用 operator new[]

Live demo