Initialization of array on heap
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: 开发者_如何学JAVAexpected 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;
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 RAII idiom).
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.
For stack-allocated arrays you can consider std::array
, should you need them.
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]);
You can define constant array, like myConstArray[] = {1, 2, 3} and do memcpy after new int[3].
{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.
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.
EDIT: You could also do it like this (std::vector still preferable):
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.
EDIT2: My answer is only valid for C++03, as other people mentioned C++0x has some improvements to this.
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}
.
There is no good solution in C++98/C++03.
If you want a general answer that works for all types, 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.
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.
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).
You can also initialize it as follows:
int * myArray = new int[3];
*myarray=1;
*(myarray+1)=2;
*(myarray+2)=3;
精彩评论