在堆上初始化数组

问题描述 投票:13回答:6

我如何手动在堆上的数组中初始化值?如果数组是局部变量(在堆栈中),则可以使用非常优雅和简单的方法来完成,如下所示:

int myArray[3] = {1,2,3};

很遗憾,以下代码

int * myArray = new int[3];
myArray = {1,2,3};

通过编译输出错误

error: expected primary-expression before ‘{’ token
error: expected `;' before ‘{’ token

我必须使用循环,还是这样不太优雅?

myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
c++ stack memory-management heap
6个回答
4
投票

这很有趣:Pushing an array into a vector

但是,如果这样做对您没有帮助,请尝试以下操作:

#include <algorithm>
...


const int length = 32;

int stack_array[length] = { 0 ,32, 54, ... }
int* array = new int[length];

std::copy(array, array + length, &stack_array[0]);

3
投票

您可以定义常量数组,例如myConstArray [] = {1,2,3},并在新int [3]之后执行memcpy。


2
投票

{1,2,3}是非常有限的语法,特定于POD结构初始化(显然,C样式的数组也被认为是一种)。您唯一可以做的就是int x[] = {1,2,3};int x[3] = {1,2,3};,但您既不能做int x[3]; x={1,2,3};,也不能在其他任何地方使用{1,2,3}

[如果您正在使用C ++,则最好使用std :: vector之类的东西来代替C样式的数组,因为它们被认为是危险的-例如,您不知道它们的大小,必须用delete[]删除它们,不是正常的delete。但是,使用std :: vector仍然会遇到相同的初始化问题。如果我经常使用此类初始化,则很可能会创建一个宏,该宏分配给虚拟局部变量,然后将内存复制到目标位置。

编辑:您也可以这样做(std :: vector还是可取的):

int* NewArray(int v1, int v2, int v3) { /* allocate and initialize */ }
int* p = NewArray(1,2,3);

但是您必须使用不同数量的参数来覆盖该函数,或者使用同样不安全的va_arg。

EDIT2:我的答案仅对C ++ 03有效,因为其他人提到C ++ 0x对此有所改进。


0
投票

C ++ 0x标准具有称为initializer_list的特殊类型和特殊语法(表达式{1, 2, 3}的类型为std::initializer_list<int>)。 std::vectorstd::array具有其构造函数,因此您可以编写vector<int> v = {1, 2, 3}

[C ++ 98 / C ++ 03中没有好的解决方案。


0
投票

如果您想要适用于all类型的一般答案,那么您要做的是:

  1. malloc()或运算符new()以创建正确长度的未初始化存储的数组,该数组的大小由nelts * sizeof(T)

  2. 为每个元素的构造函数的参数组成一个数组。

  3. 使用对应的参数将放置形式的构造函数应用于每个元素。

这仅在相同的构造函数将对每个元素都起作用的情况下起作用。否则,您将需要更复杂的数据结构和算法来为每个元素选择正确的构造函数。

这种情况的特殊情况是使用实际元素的数组并使用copy构造函数,而特殊情况是当类型为POD时,您可以只使用memcpy一次构造批次。

如果构造函数接受两个参数,则需要编写一个启动程序(包装程序)。例如:

pair<double> init_data[] = {make_pair(1.0,0.0), make_pair(3.0,4.0)};
void init(void *p, pair<double> d) { new (p) complex(d.first, d.second); }

并使用它而不是new(p)。


0
投票

今天可以使用以下语法完成:

int * myHeapArray = new int [3] {1, 2, 3};

注意,您必须将要分配的结构的大小与初始化列表的大小相匹配。

由于我要回答几年前发布的问题,所以值得一提的是,现代C ++不鼓励使用newdelete和本机(或裸露)指针。倾向于使用std::unique_ptrstd::shared_ptr等处理程序,因为它们会自动释放其拥有的内存(请检查RAII习惯用法)。

在这种特殊情况下,std::vector将提供所有这些功能:堆分配的数据,初始化列表的使用(例如{1, 2, 3}),处理程序和移动语义以及其他功能。

对于堆栈分配的数组,可以在需要时考虑使用std::array

© www.soinside.com 2019 - 2024. All rights reserved.