C++ 堆上数组的初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4571155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initialization of array on heap
提问by Radek Simko
How do i manually initiate values in array on heap? If the array is local variable (in stack), it can be done very elegant and easy way, like this:
如何在堆上手动启动数组中的值?如果数组是局部变量(在堆栈中),则可以通过非常优雅和简单的方式完成,如下所示:
int myArray[3] = {1,2,3};
Unfortunately, following code
不幸的是,以下代码
int * myArray = new int[3];
myArray = {1,2,3};
outputs an error by compiling
通过编译输出错误
error: expected primary-expression before ‘{' token
error: expected `;' before ‘{' token
Do i have to use cycle, or not-so-much-elegant way like this?
我是否必须使用循环,或者像这样不太优雅的方式?
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
采纳答案by langerra.com
This is interesting: Pushing an array into a vector
这很有趣:将数组推入向量
However, if that doesn't do it for you try the following:
但是,如果这对您不起作用,请尝试以下操作:
#include <algorithm>
...
const int length = 32;
int stack_array[length] = { 0 ,32, 54, ... }
int* array = new int[length];
std::copy(stack_array, stack_array + length, &array[0]);
回答by Nickolay Olshevsky
You can define constant array, like myConstArray[] = {1, 2, 3} and do memcpy after new int[3].
您可以定义常量数组,例如 myConstArray[] = {1, 2, 3} 并在 new int[3] 之后执行 memcpy。
回答by Roman L
{1,2,3}
is a very limited syntax, specific to POD structure initialization (apparently C-style array was considered one too). The only thing you can do is like int x[] = {1,2,3};
or int x[3] = {1,2,3};
, but you can't do neither int x[3]; x={1,2,3};
nor use {1,2,3}
in any other place.
{1,2,3}
是一种非常有限的语法,特定于 POD 结构初始化(显然 C 风格的数组也被认为是一种)。你唯一能做的就是 likeint x[] = {1,2,3};
或int x[3] = {1,2,3};
,但你不能在任何其他地方做int x[3]; x={1,2,3};
或使用{1,2,3}
。
If you are doing C++, it is preferable to use something like std::vector instead of C-style arrays, as they are considered dangerous - for example you can't know their size and must delete them with a delete[]
, not a normal delete
. With std::vector you will still have the same initialization problem, though. If I used such initialization a lot, I would most probably create a macro assigning to a dummy local variable and then copying memory to the destination.
如果您正在使用 C++,最好使用 std::vector 之类的东西而不是 C 风格的数组,因为它们被认为是危险的——例如,您无法知道它们的大小并且必须使用delete[]
而非普通的删除它们delete
。但是,使用 std::vector 您仍然会遇到相同的初始化问题。如果我经常使用这样的初始化,我很可能会创建一个宏分配给一个虚拟局部变量,然后将内存复制到目标。
EDIT: You could also do it like this (std::vector still preferable):
编辑:你也可以这样做(std::vector 仍然更可取):
int* NewArray(int v1, int v2, int v3) { /* allocate and initialize */ }
int* p = NewArray(1,2,3);
but then you'll have to override the function with different number of arguments, or use va_arg which is, again, unsafe.
但是你必须用不同数量的参数覆盖函数,或者使用 va_arg ,这同样是不安全的。
EDIT2: My answer is only valid for C++03, as other people mentioned C++0x has some improvements to this.
EDIT2:我的回答仅对 C++03 有效,因为其他人提到 C++0x 对此有一些改进。
回答by crazylammer
C++0x standard has the special type called initializer_list
and the special syntax for it (type of expression {1, 2, 3}
is std::initializer_list<int>
). std::vector
and std::array
have constructors from it, so you can write vector<int> v = {1, 2, 3}
.
C++0x 标准具有称为特殊类型的特殊类型initializer_list
及其特殊语法(表达式类型{1, 2, 3}
为std::initializer_list<int>
)。std::vector
并std::array
从中获得构造函数,因此您可以编写vector<int> v = {1, 2, 3}
.
There is no good solution in C++98/C++03.
C++98/C++03中没有很好的解决方案。
回答by Yttrill
If you want a general answer that works for alltypes, then what you do is:
如果您想要一个适用于所有类型的通用答案,那么您要做的是:
malloc() or operator new() to create an array of uninitialised storage of the right length, calculated by nelts * sizeof(T)
Make an array consisting of the argument for a constructor for each element.
Apply the constructor in placement form to each element using the corresponding argument.
malloc() 或 operator new() 创建正确长度的未初始化存储数组,由 nelts * sizeof(T) 计算
为每个元素创建一个由构造函数的参数组成的数组。
使用相应的参数将布局形式的构造函数应用于每个元素。
This only works if the same constructor will do for every element. If not, you will need a more complicated data structure and algorithm to choose the right constructor for each element.
这只适用于对每个元素都使用相同的构造函数。如果没有,您将需要更复杂的数据结构和算法来为每个元素选择正确的构造函数。
A special case of this is to use an array of the actual elements and use the copy constructor, and a special case of that is when the type is a POD and you can just use memcpy to construct the lot at once.
这种情况的一个特殊情况是使用实际元素的数组并使用复制构造函数,其中一种特殊情况是类型为 POD 并且您可以立即使用 memcpy 来构造批次。
If the constructor takes two arguments, you will need to write an initiator procedure (wrapper). For example:
如果构造函数接受两个参数,您将需要编写一个启动程序(包装器)。例如:
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); }
and use that instead of just new(p).
并使用它而不仅仅是 new(p)。
回答by Fábio Pakk Selmi-Dei
This can be accomplished today with the following syntax:
这可以通过以下语法完成:
int * myHeapArray = new int [3] {1, 2, 3};
Notice you have to match the size of the structure you're allocating with the size of the initializer-list.
请注意,您必须将分配的结构的大小与初始化列表的大小相匹配。
Since I'm replying to a question posted years ago, it is worth mentioning that modern C++ discourages the use of new
, delete
and native (or naked) pointers. The use of handlers such as std::unique_ptr
and std::shared_ptr
are favored instead, since they automatically release the memory they own (check RAIIidiom).
由于我正在回复几年前发布的一个问题,值得一提的是,现代 C++ 不鼓励使用new
,delete
和本机(或裸)指针。使用处理程序如std::unique_ptr
和std::shared_ptr
青睐代替,因为它们自动释放他们所拥有的内存(检查RAII成语)。
In this particular case, std::vector
would provide all such features: heap-allocated data, use of initializer-list (like {1, 2, 3}
), handlers and move semantics among other features.
在这种特殊情况下,std::vector
将提供所有此类功能:堆分配数据、使用初始化列表(如{1, 2, 3}
)、处理程序和移动语义以及其他功能。
For stack-allocated arrays you can consider std::array
, should you need them.
对于堆栈分配的数组,您可以考虑std::array
,如果您需要它们。