c++ - 为什么我可以声明一个二维数组,它具有两个维度大小的变量而不是新的?

标签 c++ arrays llvm compiler-optimization language-features

正如问题所述,这是可行的:

#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 时会发生什么,我被告知声明的数组应该(并且可能)只有常量维度,并且在需要时未知大小的数组,应始终考虑 newdeletevector

我没有得到的这两个解决方案有什么优缺点,还是它们就是这样?

顺便说一下,我正在使用 Apple 的 LLVM 编译器。

最佳答案

这两种形式都不符合 C++ 标准,因为该标准不支持可变长度数组 (VLA)(有趣的是,C99 支持 - 但 C 不是 C++)。然而,一些编译器有一个扩展来支持这个,包括你的编译器:

From Clang's Manual :

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/

相关文章:

ios - 在 swift 中读取并保存在数组中设置数组

javascript - 如何遍历收缩数组

C++ 构造函数具有内部链接但未定义 [-Wundefined-internal]

c++ - __declspec(dllexport) 嵌套类

javascript:变量定义与函数未定义

gcc - llvm 有 binutils 吗?

c++ - 存在什么样的堆栈展开库,有什么区别?

llvm - 性能比较 - gcc 和 llvm-gcc

c++ - 如何使用 vector 来存储形状?

c++ - 为什么将 const std::string& 传递给构造函数不允许将其绑定(bind)到初始化列表中的 const std::string& 成员变量?