以下是代码:
foo(int n){
int array[n];
}
我知道这是无效的语法,并且它无效是因为C++标准要求数组大小在编译时设置(虽然有些编译器支持以下语法)。
但是,我也知道以下是有效的语法:
bar(int n){
int *array = new int[n];
}
我不明白为什么允许这样做,难道这不就像创建一个在运行时确定大小的数组吗?如果需要这样做,这是一种好的实践方法还是应该使用vector呢?
std::dynarray
,它可以像 std::vector
一样在堆上分配,因为 std::vector
并不总是你所需要的(它可以增长,需要可移动/可复制类型,以及默认构造函数等)。 - mipstd::unique_ptr<T[]>
。它可以在运行时创建具有大小,但是创建后大小不能更改,内容也不会被移动。但是对于默认构造函数没有帮助。 - Ben Voigtmalloc
、new
或其他某种内存管理器。unique_ptr<T[]> array{new T[n]};
unique_ptr
。不过,在什么情况下使用它比仅使用 vector
更可取呢? - Pradhannew int[n]
int[n]
不是类型。C++对“使用数组的new”和“不使用数组的new”有所不同。N3337标准草案中对new
进行了如下解释:int array[n];
typedef
中。typedef int variable_array[n];
这与C99 VLAs不同,那里两者都被允许。
我应该使用向量吗?
是的,你应该。除非你有很强的理由不这样做(在过去7年中,我只有一次使用了new
- 当我为学校作业实现vector
时), 你应该始终使用向量。
int array[n]
在编译时在调用堆栈上分配一个固定长度的数组,因此需要在编译时知道 n
的值(除非使用特定于编译器的扩展允许在运行时进行分配,但数组仍然在堆栈上)。
int *array = new int[n]
在运行时在堆上分配一个动态长度的数组,因此不需要在编译时知道 n
的值。
int func(int variable)
{
long array[variable]; // VLA feature
// loop over array
for (size_t i = 0; i < sizeof array / sizeof array[0]; i++) {
// the above sizeof is also a VLA feature: it yields the dynamic
// size of the array, and so is not a compile-time constant,
// unlike other uses of sizeof!
}
}
int *p = new int[variable];
与VLA不同的是,这个对象将持续存在直到使用delete []
显式销毁,并且可以从周围的范围返回。
new T[n]
基本上就是“动态数组”的定义。你说动态数组不能是VLA,但在我看来,所有的动态数组都是VLA。这句话还暗示结构体内的数组是动态数组,但这与我熟悉的定义不符。结构体内的数组有时可能具有动态作用域,但即使如此也是勉强算动态数组。 - Mooing Duck因为它具有不同的语义:
如果n
是一个编译时常量(与您的示例不同):
int array[n]; //valid iff n is compile-time constant, space known at compile-time
但是考虑当 n
是运行时的值时:
int array[n]; //Cannot have a static array with a runtime value in C++
int * array = new int[n]; //This works because it happens at run-time,
// not at compile-time! Different semantics, similar syntax.
在C99中,您可以为数组设置运行时n
,并且空间将在运行时在堆栈中创建。目前有一些类似的扩展提案用于C++,但是还没有成为标准。
operator new
的数组形式,这种方式明确允许第一维是可变的。5
。你可以像这样写:foo(){
int array[5]; // raw array with fixed size 5
}
n
来指定将要分配的内存空间。
int array[n];
创建了一个数组对象,其类型实际上是int[n]
。而new int[n]
并不会创建数组类型;它只创建一个指向分配的数组第一个元素的int*
指针。 - Keith Thompsonint array[n]
是无效的。而这个问题问的是为什么new int[n]
是有效的。这意味着它与重复问题的距离尽可能远。 - milleniumbug