我们能否给静态数组的大小赋一个变量?

11

大家好,我想问一下,我看到过说我们只能通过指针和使用malloc或new之类的东西来声明动态数组。

int * array = new int[strlen(argv[2])];

但我已经写了

int array[strlen(argv[2])];

它没有给我任何错误提示

我读到静态数组只能通过提供常量数组大小来声明,但在这里我给了静态数组一个可变的大小

为什么是这样的,谢谢


在gcc Linux下使用它安全吗?或者在以后的阶段会出现问题吗?


1
我遇到了错误。你在用哪个编译器? - atoMerz
先生,我正在使用 GCC Linux,它运行得非常好 :/ - mainajaved
你只能在创建数组时使用const关键字,例如: const int size = strlen(argv[2]); int array[size]; - YAHOOOOO
除了这个问题,有时我会想,即使是 C99 如何处理 VLAs?它如何为在编译时甚至不知道长度的连续内存分配空间。 - iammilind
@iammilind 分配栈变量的方式与任何栈变量相同:通过从 ESP 中减去。 - tenfour
显示剩余3条评论
6个回答

18
你所拥有的是一个变长数组(VLA),它不是C++的一部分,但是它是C99的一部分。许多编译器提供此功能作为扩展。
即使是非常新的C++11也没有包括VLAs,因为整个概念不适合于C++11的高级类型系统(例如,decltype(array)是什么?),而C++提供了开箱即用的库解决方案来处理运行时大小的数组,这些解决方案更加强大(例如std::vector)。
在GCC中,使用-std=c++98/c++03/c++0x-pedantic进行编译将会给你一个警告。

2
@mainajaved:这是C语言的最新ISO标准,发布于1999年。 - Kerrek SB

5

C99支持可变长度数组,它在c99的第6.7.5.2节中定义。


3

您所编写的内容在C99中是有效的。这是一个名为“可变长度数组”的新添加功能。然而,由于没有分配失败的接口(malloc可以返回NULL,但如果无法分配VLA,则程序将崩溃或更糟,表现不稳定),因此经常不建议使用这些数组。


1
int array[strlen(argv[2])];

这肯定不是有效的C++标准代码,因为它定义了一个变长数组(VLA),在任何C++ ISO标准版本中都不允许。它仅在C99中有效。并且在非标准C或C++实现中有效。GCC提供VLA作为扩展,在C++中也是如此。

所以你只剩下第一种选择。但别担心,你甚至有更好的选择。使用std::vector<int>:

std::vector<int> array(strlen(argv[2])); 

使用它。


先生,它没有给我任何错误提示,我不明白为什么...我的所有概念都被毁了 :/ - mainajaved
正如我所说,它是作为扩展提供的。如果您正在使用GCC,则使用“-pedantic”选项编译程序,您将会得到错误提示。 - Nawaz
好的,明白了,谢谢您。另外,能否给我一个使用“-pendantic”选项进行编译的示例?我在任何地方都没有找到它。 - mainajaved

1

一些编译器并不完全符合C++标准。你所指出的在MinGW中是可能的(如果我没记错),但在大多数其他编译器(如Visual C++)中是不可能的。

实际上,在幕后发生的事情是,编译器会更改您的代码以使用动态分配的数组。

我建议不要使用这种非标准的便利。


我意识到你可能在回答问题的 C++ 部分,如果将问题视为这样,你完全是正确的,但对于一个 C 问题来说,你的回答是完全错误的。变长数组是标准的,通常分配在栈上,Visual C 之所以不支持它们,仅仅是因为它不符合 C99 标准。 - Pascal Cuoq
@Pascal 你说得对。我编辑了答案,以明确我在谈论C++。 - Paul Manta

1

这样做是不安全的。栈的大小是有限的,基于用户输入从中分配内存可能会导致堆栈溢出。

对于C++,请使用std::vector<>

其他人已经解释了为什么它“有效”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接