如何使用 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
有效?
注意:我的目标是了解分配 p
和 q
的意外行为。正如其他人指出的那样,有许多直接的方法可以解决这个问题。例如,在我的例子中,我使用一个指针来表示数组是可选的——它可能存在也可能不存在——所以我会这样做:
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;
}
但是我不建议您自己管理 new
和 delete
,除非您绝对确定自己需要这样做。
这是 new
的行为,有点令人惊讶。即使 ArrayOf10Ints
是 int[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[]
。
我有一个关于指针和数组的特殊情况。
如何在堆上分配固定大小(自动)的数组?让我们立即进入代码以了解我要问的问题:
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
有效?
注意:我的目标是了解分配 p
和 q
的意外行为。正如其他人指出的那样,有许多直接的方法可以解决这个问题。例如,在我的例子中,我使用一个指针来表示数组是可选的——它可能存在也可能不存在——所以我会这样做:
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;
}
但是我不建议您自己管理 new
和 delete
,除非您绝对确定自己需要这样做。
这是 new
的行为,有点令人惊讶。即使 ArrayOf10Ints
是 int[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[]
。