Initialization of array on heap

坚强是说给别人听的谎言 提交于 2019-12-04 02:30:02
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(array, array + length, &stack_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:

  1. malloc() or operator new() to create an array of uninitialised storage of the right length, calculated by nelts * sizeof(T)

  2. Make an array consisting of the argument for a constructor for each element.

  3. 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).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!