Main Content

生成されたコード内の配列の表現

コード ジェネレーターは、配列要素のタイプと、配列が静的または動的メモリ割り当てのいずれを使用するかに依存する C/C++ 配列定義を生成します。生成された配列実装を、配列と生成されたコード間のインターフェイスとして使用します。

配列に対するメモリ割り当てには、次の異なる実装が必要です。

  • サイズが事前定義されたメモリしきい値に制限される固定サイズの配列または可変サイズの配列の場合、生成された C/C++ 定義は、要素の固定サイズの配列、および配列要素の総数を格納するサイズ ベクトルで構成されます。場合によっては、固定サイズの要素配列とサイズ ベクトルが構造体に格納されることもあります。この配列のメモリはプログラム スタックから得られ、静的に割り当てられます。

  • コンパイル時にサイズが制限されない配列、または事前定義されたしきい値を制限が超える配列の場合、生成された C 定義は emxArray と呼ばれるデータ構造体で構成されます。生成された C++ 定義は、coder::array クラス テンプレートで構成されます。

事前定義されたしきい値サイズ (バイト単位) は、構成オブジェクトで指定されます。パラメーターの既定値は 65536 です。coder.MexCodeConfigcoder.CodeConfig、または coder.EmbeddedCodeConfigDynamicMemoryAllocationThreshold を参照してください。

動的に割り当てられる配列では、実行時に割り当てられるサイズは現在の配列サイズに基づいて設定されます。プログラム実行中に、実行時に割り当てられるサイズを超過すると、生成されたコードはヒープから追加のメモリ領域を再割り当てし、動的な配列ストレージに追加します。

次の表に、生成されたコード内における配列表現の代表的な例をいくつか示します。

アルゴリズムの説明と配列サイズ

MATLAB® 関数

生成される C/C++ コード

固定サイズ 1 行 500 列の行ベクトルを作成します。配列は、関数 MATLAB の出力です。

生成されたコードは、プログラム スタック上で固定サイズのベクトルにメモリを割り当てます。

function B = create_vec0 %#codegen
B = zeros(1,500);
end
void create_vec0(double B[500])
{
  memset(&B[0], 0, 500U * sizeof(double));
}

配列は、生成されたコード内の関数への入力です。

固定サイズ 1 行 20 列の行ベクトルを作成します。配列を 500 要素までの制限付き可変サイズとして宣言します。この可変サイズの配列を入力配列に割り当てます。

この配列はサイズしきい値に制限されており、生成されたコード内の関数への入力です。

function create_vec1(B) %#codegen
A = zeros(1,20);
coder.varsize('A',[1 500],[0 1]);
B = A;
end
void create_vec1(double B_data[], int B_size[2])
{
  int i;
  B_size[0] = 1;
  B_size[1] = 20;
  for (i = 0; i < 20; i++) {
    B_data[i] = 1.0;
  }
}

メモ

生成されたコードは、関数パラメーター内の入力を含みます。

ローカルの固定サイズの 1 行 20000 列の行ベクトルを作成します。配列を 30,000 要素までの制限付き可変サイズとして宣言します。

可変サイズの配列が事前定義された動的メモリ割り当てしきい値を超過します。この配列はヒープ メモリに格納されます。

生成されたコードは、関数パラメーター内の出力配列を含みます。

function B = create_vec2() %#codegen
A = ones(1,20000);
coder.varsize("A",[1 30000], [0 1]);
B = [1 A];
end

C:

void create_vec2(emxArray_real_T *B)
{
  double *B_data;
  int i;
  i = B->size[0] * B->size[1];
  B->size[0] = 1;
  B->size[1] = 20001;
  emxEnsureCapacity_real_T(B, i);
  B_data = B->data;
  B_data[0] = 1.0;
  for (i = 0; i < 20000; i++) {
    B_data[i + 1] = 1.0;
  }
}

C++:

void create_vec2(coder::array<double, 2U> &B)
{
  B.set_size(1, 20001);
  B[0] = 1.0;
  for (int i{0}; i < 20000; i++) {
    B[i + 1] = 1.0;
  }
}

制限されていない整数入力によってサイズが決定される配列を作成します。

生成される配列のサイズはコンパイル時に不明であり、制限されません。

function y = create_vec3(n) %#codegen
y = ones(1,n,'int8');

C:

void create_vec3(double n, emxArray_int8_T *y)
{
  int i;
  int loop_ub_tmp;
  signed char *y_data;
  i = y->size[0] * y->size[1];
  y->size[0] = 1;
  loop_ub_tmp = (int)n;
  y->size[1] = (int)n;
  emxEnsureCapacity_int8_T(y, i);
  y_data = y->data;
  for (i = 0; i < loop_ub_tmp; i++) {
    y_data[i] = 1;
  }
}

C++:

void create_vec3(double n, coder::array<signed char, 2U> &y)
{
  int loop_ub_tmp;
  loop_ub_tmp = static_cast<int>(n);
  y.set_size(1, loop_ub_tmp);
  for (int i{0}; i < loop_ub_tmp; i++) {
    y[i] = 1;
  }
}

emxArray データ構造体の詳細については、生成された関数インターフェイスでの C 配列の使用を参照してください。

coder::array クラス テンプレートの詳細については、生成された関数インターフェイスでの動的に割り当てられた C++ 配列の使用を参照してください。

インターフェイス生成のカスタマイズ

既定では、生成された C++ コードは、coder::array テンプレートを使用して動的に割り当てられた配列を実装します。C スタイルの emxArray データ構造体を使用して動的に割り当てられた配列を実装する C++ コードを生成することもできます。C スタイルの emxArray データ構造体を生成するには、次のいずれかを行います。

  • コード構成オブジェクト (coder.MexCodeConfigcoder.CodeConfig または coder.EmbeddedCodeConfig) 内で DynamicMemoryAllocationInterface パラメーターを 'C' に設定する。

  • あるいは、MATLAB Coder™ アプリの [メモリ] タブで、[動的メモリ割り当てインターフェイス][C スタイルの EmxArray を使用] に設定する。

生成されたコード内の可変サイズの配列用に動的に割り当てられる配列を作成するには、以下のいずれかを行います。

  • EnableDynamicMemoryAllocation フラグを true に設定する。

  • あるいは、MATLAB Coder アプリの [メモリ] タブで、[動的メモリ割り当てを有効化] オプションを選択する。

既定では、しきい値サイズ内に制限される配列は、生成されるコードで動的な割り当てを使用しません。または、動的メモリ割り当てを無効にして、動的メモリ割り当てしきい値を変更することもできます。可変サイズの配列に対するメモリ割り当ての制御を参照してください。

参考

| | |

関連するトピック