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

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

本文关键字:数组 new 使用 一个 创建      更新时间:2023-10-16

我有一个关于指针和数组的角大小写。

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

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;

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

这在[Epr.new]/5中指定

当分配的对象是数组时(也就是说,使用noptr new declarator语法,或者new type idtype id表示数组类型),新表达式会产生一个指向数组初始元素(如果有)的指针

因此,在您的示例中,new表达式返回一个int *,因此出现错误。

一个变通方法是按照显示的操作

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

或者将阵列放置在struct中,或者使用std::array

注意,即使你要写

int* p = new ArrayOf10Ints;

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

实时演示

注意:由于超出讨论范围的原因,我需要做这个

当然不会,因为错误的事情是行不通的。

请改用std::array<int,10>。这个代码应该工作得很顺利:

typedef array<int,10> ArrayOf10Ints;
int f() {
     ArrayOf10Ints * p = new ArrayOf10Ints;
     // ...
     delete p;
}

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