C++中的动态数组声明
Posted
技术标签:
【中文标题】C++中的动态数组声明【英文标题】:dynamic array declaration in c++ 【发布时间】:2018-03-28 12:00:02 【问题描述】:我见过两种在 C++ 中声明动态数组的方法。一种是使用 new 运算符:
int *arr = new int [size];
和其他直接声明:
int arr[size];
注意:这里注意 size 是一个变量,其值将由用户在运行时提供。 问题是在 C++ 中声明动态数组的最佳方法是什么?
【问题讨论】:
第二个不是标准C++,它是一个编译器扩展(一些编译器支持) @Gaurav Sahu 有什么问题? 您能具体说明您的问题吗? 第二种语法是有效的 C 但不是 C++。这两件事有不同的含义,C++ 结构被翻译成 C 为 `int* arr = (int*)malloc(sizeof(int) * size)。 C 构造不能直接转换为 C++。 为什么不使用 std::vector-std::array? 【参考方案1】:假设您的问题是“什么更好?”。
第二种,直接创建数组,在栈上创建数组,第一个在堆上。第二种称为可变长度数组 (VLA),它是非标准 C++ 且不可移植,但在 C 中它是标准的。 GNU C++ 编译器支持这一点,但其他编译器不支持这一点。在内部,数组的分配方式与 alloca
(POSIX)/__builtin_alloca
(GNU) 一样,它扩展了堆栈帧。 variadic-length-array 可以粉碎你的堆栈(可能会产生一个 SIGSEGV,但也可能会破坏其他数据),而 new-operator 会抛出一个可捕获的异常。 (但是,使用递归函数可以粉碎你的堆栈以同样的方式......)。当您知道大小相对较小时,使用 VLA 并不是一个坏习惯。当需要多次分配数组时(VLA 的分配比堆上的分配更快),VLA 甚至可以提高性能。由于 VLA live 在堆栈上,它不需要是 free
d/delete
d,它会在函数退出时自动释放。
这适用于 GNU 编译器:VLA 确实在销毁时调用析构函数,但分配给 alloca
/__builtin_alloca
的内存将在函数结束时释放,因为内存(分配给 malloc
)已释放free
。
作为结论,我认为new
的分配更适合大多数问题。但是 VLA 有利于函数中的本地快速内存分配。没有可移植的方法从函数返回 VLA(无需通过程序集进行破解)(您可以从函数返回具有恒定大小的数组,但需要在签名中指定)。为此,有std::array
和std::vector
,我建议使用它而不是手工制作的内存管理(分配new
和delete
或Cs malloc
和free
),它没有被释放当引发异常时。如果您需要使用此类函数,则内存管理应始终嵌套在类的构造函数和析构函数中。当对象超出范围时,总是会调用析构函数,因此不会发生内存泄漏。
你不能用 VLA 和 new
/delete
做的一件事是快速调整大小。甚至std::vector
也不使用它。它是通过 C 函数 realloc
完成的,它试图将缓冲区保持在原位。当你需要这个时,你可以轻松地设计一个类似std::vector
的类,它应该在析构函数中调用free
。要销毁调用element.~T()
的元素,其中T
是element
的类型。
但是std::vector
试图通过分配具有额外空间的缓冲区来提高调整大小的性能。
【讨论】:
alloca
既不是标准 C++ 也不是 C【参考方案2】:
这两种方法的主要区别是第一种从Free-store(Heap)分配内存,第二种从堆栈分配。事实上,第二个不好用,因为堆栈内存与堆相比在空间上非常有限。同样,第一条语句显然返回指向分配内存中第一个元素的指针,而第二条语句返回数组本身。
【讨论】:
以上是关于C++中的动态数组声明的主要内容,如果未能解决你的问题,请参考以下文章