为什么operator new不能构造非常量大小的多维数组?

use*_*538 1 c++ arrays multidimensional-array variable-length-array

我可以为一维数组编写operator new,如下所示:

int n{3};
new int[n];
Run Code Online (Sandbox Code Playgroud)

它至少分配sizeof(int) * n字节。但是当我想创建二维或多维数组时,只有第一维可能是非常量:

int n{3};
new int[n][3]; //ok
new int[n][n]; //error;
Run Code Online (Sandbox Code Playgroud)

为什么会出现这样的限制?确定至少需要sizeof(int) * n * n分配字节数是否有任何困难?

AnT*_*AnT 5

本例中的问题不在于确定要分配多少内存。正如您自己指出的那样,这部分实际上很简单。

问题是事后组织对这样的数组的访问。如果您知道,C++ 中的多维数组被实现为具有索引重新映射的线性(一维)数组。例如,当您声明

int a[N][M];
Run Code Online (Sandbox Code Playgroud)

编译器实际上int [N * M]在底层创建了一个数组。当您稍后访问它时a[i][j],后者会简单地隐式转换为对 的访问a[i * M + j]。C++编译器坚持M在编译时知道 的值(同时,请注意, 的值N根本不参与索引重新计算公式)。

这就是为什么在数组衰减为指针的情况下,多维数组的第一个大小并不重要,而第二个、第三个和更多大小必须是编译时常量的原因。这也决定了施加的限制new []

PS C 语言支持可变长度数组,允许所有大小都是运行时值。这需要在幕后进行额外的工作,例如将上面示例中的M和的运行时值N与数组一起存储。a这最终被认为不适合 C++。