我一直在教自己编程几年,我确信如果你需要变量编号的数组声明,你需要使用malloc
或new
。
今天我发现这在g ++版本4.4.4下编译,没有警告或错误:
#include <iostream>
using namespace std;
int main()
{
int size_array;
cin >> size_array;
int iTable[size_array];
for(int i=0;i < size_array;i++)
iTable[i]=i*i;
for(int i=0;i < size_array;i++)
cout << iTable[i] << endl;
return 0;
}
如果你使用gcc(在用cout
和cin
和printf
更改scanf
和size_array
后)它也会完全正常编译
在Visual Studio下,此代码无法编译,因为{{1}}不是常量。
什么时候改变了?这是一种安全的方法吗?
答案 0 :(得分:9)
这是C99功能 - VLA - 它不是标准c ++的一部分。如果您的编译器支持它并且您不需要可移植性,则可以使用它。如果编译器支持它,那么使用起来非常安全 - 但使用非标准功能是一个坏习惯。
答案 1 :(得分:5)
这是compiler extension of gcc,不是标准。
答案 2 :(得分:2)
这根本不安全。它可能会破坏你的筹码。
答案 3 :(得分:2)
请参阅http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.20。
简单地说,在C99中,这被称为VLA并且是标准的一部分(如果我错了,请纠正我),但在C ++中,这不是标准的一部分。如果您需要此功能,请改用std:vector
。
答案 4 :(得分:0)
这取决于您是在编写C还是C ++。我假设C和c ++一样,你最好使用std :: vector而不是数组。
在C中,它取决于您使用的是哪个版本。当且仅当您使用C99标准编译器时,数组才能在运行时从变量中获取其大小,否则必须在编译时定义大小。 Visual Studio不支持动态数组 - 请参阅MSDN
C ++使用C89标准,因此需要在编译时设置大小。
因此,在您的情况下,您需要查看传递给编译器的标志。
如@Eric所述,代码是C ++,因此正在运行的编译器使用非标准扩展,因此对于gnu,我会添加flags来强制执行标准,例如-ansi或-std = c ++ 98 and -pedantic
答案 5 :(得分:0)
GCC的扩展模仿C99可变长度阵列。它不是标准的C ++。
但是,即使你关闭,发布的代码也可以编译。该标准不需要对这种情况进行诊断:它是未定义的行为,而不是错误。
在非常明显的情况下,编译器可能会选择阻止您编写此文件,但是否则可以让您自由地失败。
结论:不要被编译所迷惑。这仍然是坏事和错误。
答案 6 :(得分:0)
您可以使用alloca(Windows上的_alloca)在C或C ++中获得此功能。 std :: vector不是替代品:它在堆上分配,使用new,调用malloc,这可能很昂贵。
有一个很好的理由可以让你想要一个数组,其长度是在堆栈上分配的运行时确定的:它真的很快。假设你有一个频繁执行的循环但是有一个依赖运行时某些东西的数组(比如画布小部件的大小)。你不能只是对一个数字进行硬编码:当我们都得到36“300 dpi视网膜显示屏并且像素[2400]不再安全时,你的程序会崩溃。但你不想要新的,或者你的循环命中malloc并慢慢来。
虽然对于大型数组,最好有一个对函数是静态的std :: vector,但只有在必要时才会调整大小(更大),因为堆栈的大小有限。
(见http://msdn.microsoft.com/en-us/library/wb1s57t5(VS.71).aspx)
答案 7 :(得分:0)
如果使用c99,可以使用该功能。
你必须非常小心尺寸的价值。一个很大的值会溢出你的堆栈,你的过程可能会疯狂。