正如问题所述,这是可行的:
#include <iostream>
int main(int argc, char *argv[])
{
unsigned short int i;
std::cin >> i;
unsigned long long int k[i][i];
}
这里我声明了一个大小为 i x i 的数组,两个维度都是变量。
但不是这个:
#include <iostream>
int main(int argc, char *argv[])
{
unsigned short int i;
std::cin >> i;
unsigned long long int** k = new int[i][i];
delete[] k;
}
我收到一条编译器消息告诉我
error: only the first dimension of an allocated array may have dynamic size
我被迫这样做:
#include <iostream>
int main(int argc, char *argv[])
{
unsigned short int i;
std::cin >> i;
unsigned long long int** k = new unsigned long long int*[i];
for ( unsigned short int idx = 0 ; idx < i ; ++ i )
k[idx] = new unsigned long long int[i];
for ( unsigned short int idx = 0 ; idx < i ; ++ i )
delete[] k[idx];
delete[] k;
}
据我了解,new 和 delete 用于在堆上分配一些东西,而不是在堆栈上,当它超出范围时不会被删除,并且对于跨函数和对象传递数据等很有用。
我不明白的是,当我在第一个示例中声明 k
时会发生什么,我被告知声明的数组应该(并且可能)只有常量维度,并且在需要时未知大小的数组,应始终考虑 new
和 delete
或 vector
。
我没有得到的这两个解决方案有什么优缺点,还是它们就是这样?
顺便说一下,我正在使用 Apple 的 LLVM 编译器。
最佳答案
这两种形式都不符合 C++ 标准,因为该标准不支持可变长度数组 (VLA)(有趣的是,C99 支持 - 但 C 不是 C++)。然而,一些编译器有一个扩展来支持这个,包括你的编译器:
Clang supports such variable length arrays in very limited circumstances for compatibility with GNU C and C99 programs:
- The element type of a variable length array must be a POD ("plain old data") type, which means that it cannot have any user-declared constructors or destructors, any base classes, or any members of non-POD type. All C types are POD types.
- Variable length arrays cannot be used as the type of a non-type template parameter.
但鉴于扩展已经到位,为什么您的第二个代码段不起作用?那是因为 VLA 只适用于自动变量 - 即参数或局部变量。 k
是自动的,但它只是一个指针 - 数组本身由 new int[i][i]
定义,它在堆上分配并且显然不是 一个自动变量。
您可以在 the relevant GCC manual section 上阅读更多相关信息.
关于c++ - 为什么我可以声明一个二维数组,它具有两个维度大小的变量而不是新的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16873709/