c ++中的动态数组声明

时间:2018-03-28 12:00:03

标签: c++ arrays dynamic declaration

我已经看到两种在C ++中声明动态数组的方法。一个是使用新的运算符:

.center {
  margin: 50% auto;
  width: 370px;
}

和其他人直接宣布:

int *arr = new int [size];

注意:请注意,size是一个变量,其值将由用户在运行时提供。 问题是在C ++中声明动态数组的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

假设你的问题是“什么更好?”。

第二个,直接创建数组,在堆栈上创建数组,第一个在堆上。第二个叫做variadic-length-array(VLA),它是非标准的C ++而不是可移植的,但在C中它是标准的。 GNU C ++编译器支持这一点,但其他人不支持。在内部,数组的分配与alloca(POSIX)/ __builtin_alloca(GNU)一样,它扩展了堆栈帧。 variadic-length-array可以粉碎你的堆栈有一个大的大小(可能产生一个SIGSEGV,但也可能破坏其他数据),而new-operator会抛出一个可捕获的异常。 (但是,使用递归函数可以以同样的方式粉碎你的堆栈......)。当您知道尺寸相对较小时,使用VLA并不是一种不好的做法。当需要多次分配阵列时,VLA甚至可以提高性能(VLA的分配比堆上的分配快)。由于堆栈上的VLA 生活,它不需要free d / delete d,它会在函数退出时自动释放。 这适用于GNU编译器:VLA在销毁时调用析构函数,但是使用alloca / __builtin_alloca分配的内存将在函数末尾作为内存释放(用{分配) {1}})使用malloc释放。

作为结论,我认为使用free的分配对大多数问题更好。但是VLA适用于函数本地的快速内存分配。没有可移植的方法从函数返回VLA(没有黑客攻击程序集)(您可以从函数返回具有常量大小的数组,但需要在签名中指定)。为此,有newstd::array,我建议使用它来代替手工内存管理(使用std::vectornew或Cs delete进行分配和malloc),在引发异常时不会释放。如果需要使用这些函数,内存管理应始终嵌套在类的构造函数和析构函数中。当对象超出范围时,总是调用析构函数,因此没有内存泄漏。

使用VLA和free / new无法做到的一件事是快速调整大小。即使delete也不使用它。它是用C函数std::vector完成的,它试图将缓冲区保持在原位。当你需要这个时,你可以很容易地设计一个类似realloc的类,它应该在析构函数中调用std::vector。要销毁您调用free的元素,element.~T()的类型为T

但是element尝试通过分配带有额外空间的缓冲区来提高调整大小的性能。

答案 1 :(得分:1)

两种方法的主要区别在于,第一种方法是从Free-store(Heap)分配内存,第二种方法是从堆栈中分配内存。实际上第二个不好用,因为与堆相比,堆栈内存在空间上非常有限。此外,第一个语句显然返回指向已分配内存中第一个元素的指针,而第二个返回数组本身。