我已经看到两种在C ++中声明动态数组的方法。一个是使用新的运算符:
.center {
margin: 50% auto;
width: 370px;
}
和其他人直接宣布:
int *arr = new int [size];
注意:请注意,size是一个变量,其值将由用户在运行时提供。 问题是在C ++中声明动态数组的最佳方法是什么?
答案 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(没有黑客攻击程序集)(您可以从函数返回具有常量大小的数组,但需要在签名中指定)。为此,有new
和std::array
,我建议使用它来代替手工内存管理(使用std::vector
和new
或Cs delete
进行分配和malloc
),在引发异常时不会释放。如果需要使用这些函数,内存管理应始终嵌套在类的构造函数和析构函数中。当对象超出范围时,总是调用析构函数,因此没有内存泄漏。
使用VLA和free
/ new
无法做到的一件事是快速调整大小。即使delete
也不使用它。它是用C函数std::vector
完成的,它试图将缓冲区保持在原位。当你需要这个时,你可以很容易地设计一个类似realloc
的类,它应该在析构函数中调用std::vector
。要销毁您调用free
的元素,element.~T()
的类型为T
。
但是element
尝试通过分配带有额外空间的缓冲区来提高调整大小的性能。
答案 1 :(得分:1)
两种方法的主要区别在于,第一种方法是从Free-store(Heap)分配内存,第二种方法是从堆栈中分配内存。实际上第二个不好用,因为与堆相比,堆栈内存在空间上非常有限。此外,第一个语句显然返回指向已分配内存中第一个元素的指针,而第二个返回数组本身。