在堆上初始化数组

时间:2010-12-31 16:30:32

标签: c++ stack memory-management heap

如何在堆上手动启动数组中的值? 如果数组是局部变量(在堆栈中),它可以非常优雅和简单的方式完成,如下所示:

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;

6 个答案:

答案 0 :(得分: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]);

答案 1 :(得分:3)

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

答案 2 :(得分: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风格的数组,因为它们被认为是危险的 - 例如,您无法知道它们的大小,必须使用{{删除它们1}},而不是正常的delete[]。但是使用std :: vector,你仍然会遇到相同的初始化问题。如果我经常使用这样的初始化,我很可能会创建一个宏分配给一个虚拟局部变量,然后将内存复制到目的地。

编辑:你也可以这样做(std :: vector仍然更可取):

delete

但是你必须用不同数量的参数覆盖函数,或者使用va_arg,这又是不安全的。

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

答案 3 :(得分: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中没有很好的解决方案。

答案 4 :(得分:0)

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

  1. malloc()或operator new()创建一个正确长度的未初始化存储数组,由nelts * sizeof(T)计算

  2. 创建一个数组,其中包含每个元素的构造函数的参数。

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

  4. 这仅适用于相同的构造函数将对每个元素执行的操作。如果没有,您将需要更复杂的数据结构和算法来为每个元素选择正确的构造函数。

    这种情况的一个特例是使用实际元素的数组并使用复制构造函数,其特殊情况是当类型为POD时,您可以使用memcpy一次构造批次。 / p>

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

    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); }
    

    并使用它而不仅仅是新的(p)。

答案 5 :(得分:0)

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

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

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

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

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

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