web-dev-qa-db-ja.com

ヒープ上の配列の初期化

ヒープ上の配列の値を手動で開始するにはどうすればよいですか?配列が(スタック内の)ローカル変数である場合、次のように非常にエレガントで簡単な方法で実行できます。

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;
12
Radek Simko

これは興味深いです: 配列をベクトルにプッシュする

ただし、それでも問題が解決しない場合は、次のことを試してください。

#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]);
4
langerra.com

MyConstArray [] = {1、2、3}のように定数配列を定義し、新しいint [3]の後にmemcpyを実行できます。

3

{1,2,3}は非常に限定された構文であり、POD構造の初期化に固有です(明らかにCスタイルの配列も1つと見なされていました)。できることはint x[] = {1,2,3};またはint x[3] = {1,2,3};のようなものだけですが、int x[3]; x={1,2,3};を実行したり{1,2,3}を他の場所で使用したりすることはできません。

C++を使用している場合は、危険と見なされるため、Cスタイルの配列の代わりにstd :: vectorのようなものを使用することをお勧めします。たとえば、サイズがわからないため、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++ 0xがこれにいくつかの改善を持っていると述べたように、私の答えはC++ 03に対してのみ有効です。

2
Roman L

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
crazylammer

allタイプで機能する一般的な回答が必要な場合は、次のようにします。

  1. malloc()または演算子new()を使用して、nelts * sizeof(T)で計算された、適切な長さの初期化されていないストレージの配列を作成します。

  2. 各要素のコンストラクターの引数で構成される配列を作成します。

  3. 対応する引数を使用して、配置形式のコンストラクターを各要素に適用します。

これは、同じコンストラクターがすべての要素に対して機能する場合にのみ機能します。そうでない場合は、各要素に適切なコンストラクターを選択するために、より複雑なデータ構造とアルゴリズムが必要になります。

これの特殊なケースは、実際の要素の配列を使用してコピーコンストラクターを使用することです。その特殊なケースは、型がPODであり、memcpyを使用して一度にロットを構築できる場合です。

コンストラクターが2つの引数を取る場合は、イニシエータープロシージャ(ラッパー)を作成する必要があります。例えば:

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
Yttrill