new char[n]
和new (char[n])
有什么区别吗?
我在生成的代码中有第二种情况,g++ (4.8.0) 给了我
ISO C++ does not support variable-length array types [-Wvla]
这让我想到这两个是否相同。
new char[n]
表示“分配n
类型为char
的对象。new (char[n])
的意思是“分配 1 个类型为n 字符数组
的对象”吗?- 删除第一个很清楚。
- 我应该用
delete
还是delete[]
删除第二个? - 还有其他我应该注意的区别吗?
- 当软件的其他部分期待第二种情况时,我可以安全地删除括号并将第二种情况转换为第一种情况吗?
代码是由第三方软件生成的(并被软件的其他部分使用),所以我不能只是“使用 vector 代替”。
这是最小的例子:
int main (void)
{
int n(10);
int *arr = new (int[n]); // removing parentheses fixes warning
*arr = 0; // no "unused variable" warning
return 0;
}
最佳答案
这里的基本问题是 C++ 不允许数组绑定(bind) [n]
用于类型,除非 n
是一个常数表达式。 g++ 和其他一些编译器有时会允许它,但是当您开始混合可变长度数组和模板时,不可能获得一致的行为。
明显的异常(exception) 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;
}
但在语义上,在任何结尾 [C]
之后用于将类型转换为数组类型,new 表达式只关心是否处理数组。关于表达式类型的所有要求,是否使用new[]
和 delete[]
,依此类推,比如“分配的类型是数组时”,而不是“使用数组新语法时”。所以在上面的例子中,p1
的初始化, p2
, 和 p3
都是等价的,并且在所有情况下delete[]
是正确的释放形式。
p4
的初始化有效,但 p5
的代码和 p6
不是正确的 C++。当不使用 -pedantic
时,g++ 无论如何都会允许它们。 ,以此类推,我希望 p4
的初始化, p5
, 和 p6
也都是等价的。 @MM 的反汇编支持了这个结论。
所以是的,从这种表达式中删除“额外”括号应该是一个安全的改进。正确的删除是delete[]
输入。
关于c++ - new char[n] 和 new (char[n]) 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16634713/