新char [n]和new(char [n])之间的差异

Ada*_*hon 23 c++ memory-management

有什么区别new char[n]和new (char[n])?

我在生成的代码中有第二种情况,g ++(4.8.0)给了我

ISO C++ does not support variable-length array types [-Wvla]
Run Code Online (Sandbox Code Playgroud)

这让我想到这两者是否相同.

  1. new char[n]意思是"分配n类型的对象char.
  2. 是否new (char[n])意味着"分配1个类型的对象array of n chars"?
  3. 删除第一个很清楚.
  4. 我应该用delete或删除第二个delete[]?
  5. 我应该注意哪些其他差异?
  6. 我可以安全地删除括号并将第二种情况转换为第一种情况,当软件的其他部分期望第二种情况时?

代码由第三方软件生成(并由软件的其他部分使用),因此我不能只是"使用向量".

这是最小的例子:

int main (void)
{
    int n(10);
    int *arr = new (int[n]); // removing parentheses fixes warning
    *arr = 0; // no "unused variable" warning
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

asc*_*ler 10

这里的基本问题是C++不允许绑定[n]在类型中使用的数组,除非n是常量表达式.g ++和其他一些编译器有时会允许它,但是当你开始混合可变长度数组和模板时,不可能获得一致的行为.

明显的异常是int* p = new int[n];有效的,因为这里[n]语法是new表达式的一部分,而不是提供给它的类型的一部分new,并且new"知道如何"创建长度在运行时确定的数组.

// can be "constexpr" in C++11:
const int C = 12;

int main() {
    int* p1 = new int[C];
    int* p2 = new (int[C]);
    typedef int arrtype[C];
    int* p3 = new arrtype;

    int n = 10;
    int* p4 = new int[n];
    // int* p5 = new (int[n]);  // Illegal!
    // typedef int arrtype2[n]; // Illegal!
    // int* p6 = new arrtype2;

    delete[] p1;
    delete[] p2;
    delete[] p3;
    delete[] p4;
}
Run Code Online (Sandbox Code Playgroud)

但是,在语义上,在使用任何final [C]将类型转换为数组类型之后,新表达式只关心它是否处理数组.关于类型的表达式的所有要求,是否使用new[]和delete[],等等这样说:"当分配类型是数组",而不是"当使用数组新的语法".所以在上面的例子中,的初始化p1,p2以及p3都是等效的,并且在所有情况下delete[]是正确的释放形式.

初始化p4是有效的,但代码是p5和p6C++不正确.G ++不使用时,让他们无论如何-pedantic,依此类推,我期望的初始化的p4,p5和p6也全部是等价的.@ MM的反汇编支持这个结论.

所以是的,从这种表达式中删除"额外"括号应该是一种安全的改进.正确的删除是delete[]类型.


Ker*_* SB 6

  • new T[N]生成一个N类型的元素数组T.

  • new (T[N])制作一个类型的单个对象T[N].

效果是相同的(两个表达式产生一个T *指向数组的第一个元素,需要删除delete[](参见5.3.4/5),但在后一种情况下显然T[N]必须是有效类型,所以N必须是一个常量表达式,而在前一种情况下,它是array-new表达式的动态参数.