ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

メモリ管理

一時的な配列の自動クリーンアップ

MEX ファイルから MATLAB® に制御が戻るとき、左辺の引数 plhs[] に含まれる出力引数 mxArray に計算の結果が返されます。MATLAB は、この引数リストにない、MEX ファイルによって作成された mxArray を破棄します。さらに、MATLAB により、関数 mxCalloc、関数 mxMalloc または関数 mxRealloc を使用して MEX ファイルに割り当てられたメモリが解放されます。

MathWorks® では、MEX ファイル関数によって自身の一時的な配列を破棄し、動的に割り当てられた自身のメモリを解放することをお勧めしています。自動メカニズムに依存するより、ソース MEX ファイルでこのクリーンアップを実行する方がより効率的です。 しかし、MEX ファイルが正常な return ステートメントに到達しない状況がいくつかあります。

以下のような状況では正常な復帰に到達しません。

  • MATLAB で mexErrMsgTxt を呼び出す場合。

  • MATLAB で mexCallMATLAB を呼び出し、呼び出される関数がエラーを生じる場合。(ソース MEX ファイルは関数 mexCallMATLABWithTrap を使用してそのようなエラーをキャッチできますが、すべての MEX ファイルがエラーをキャッチする必要があるとは限りません)

  • ユーザーが Ctrl+C キーで、バイナリ MEX ファイルの実行を中断する場合。

  • バイナリ MEX ファイルがメモリ不足になる場合。MATLAB の out-of-memory ハンドラーが MEX ファイルを即座に終了します。

最初の 2 つのケースについては、MEX ファイルのプログラマが制御を戻す前に一時的な配列とメモリを安全にクリーンアップするようにできますが、後の 2 つではそうはいきません。その場合、メモリ リークを回避するために自動クリーンアップ メカニズムが必要です。

メモリを管理するには、MATLAB に用意されている関数の mxCallocmxFree を使用しなければなりません。同等の機能をもつ標準 C ライブラリは使用しないでください。使用するとプログラム終了を含む、予期しない結果が発生します。

この例では、MEX ファイルの変数にメモリを割り当てる方法を説明します。たとえば、関数への最初の入力 (prhs[0]) が文字列である場合、その文字列を操作するためにサイズ buflen のバッファー buf を作成します。次のステートメントは、これらの値を宣言します。

char *buf;
int buflen;

バッファーのサイズは、入力配列の次元の数および配列内のデータのサイズによって異なります。次のステートメントは、buflen のサイズを計算します。

buflen = mxGetN(prhs[0])*sizeof(mxChar)+1;

次に、buf にメモリを割り当てます。

buf = mxMalloc(buflen);

プログラムの最後に plhs 出力パラメーターとして buf を返さない場合、以下のようにメモリを解放します。

mxFree(buf);

MEX ファイルを終了する前に、一時的な配列を破棄して動的に割り当てられたメモリを解放します。ただし、そのような mxArray が出力引数リストで返される場合、関数 mexGetVariablePtr で返されている場合、構造体の作成に使用されている場合などは除きます。また、入力引数は決して削除しないでください。

関数 mxCalloc、関数 mxMalloc または関数 mxRealloc によって割り当てられたメモリを解放するには、関数 mxFree を使用します。関数 mxCreate* によって割り当てられたメモリを解放するには、関数 mxDestroyArray を使用します。

永続的な配列

関数 mexMakeArrayPersistent または関数 mexMakeMemoryPersistent を呼び出すことにより、MATLAB 自動クリーンアップから配列またはメモリの一部を除外することができます。しかし MEX ファイルがこういった永続的なオブジェクトを作成する場合、その永続的なオブジェクトが正常に破棄される前に MEX ファイルがクリアされると、メモリ リークが発生する危険があります。メモリ リークを回避するには、関数 mexAtExit を使用して、これらの関数を使用して作成されたオブジェクトのメモリを解放する関数を登録します。

たとえば、以下の単純なソース MEX ファイルは、永続的な配列の作成および適正な破棄を行います。

#include "mex.h"

static int initialized = 0;
static mxArray *persistent_array_ptr = NULL;

void cleanup(void) {
    mexPrintf("MEX-file is terminating, destroying array\n");
    mxDestroyArray(persistent_array_ptr);
}

void mexFunction(int nlhs,
    mxArray *plhs[],
    int nrhs,
    const mxArray *prhs[])
{
  if (!initialized) {
    mexPrintf("MEX-file initializing, creating array\n");
        
    /* Create persistent array and register its cleanup. */
    persistent_array_ptr = mxCreateDoubleMatrix(1, 1, mxREAL);
    mexMakeArrayPersistent(persistent_array_ptr);
    mexAtExit(cleanup);
    initialized = 1;

    /* Set the data of the array to some interesting value. */
    *mxGetPr(persistent_array_ptr) = 1.0;
  } else {
    mexPrintf("MEX-file executing; value of first array element is %g\n",
              *mxGetPr(persistent_array_ptr));
  }
}

参考

| | |

詳細

この情報は役に立ちましたか?