外部インタフェース/API | ![]() ![]() |
パフォーマンス問題に注目すると、MATLAB内部のメモリ管理モデルに変更を行う必要があります。これらの変更は、MEX-ファイルAPIの将来の機能強化の準備となっています。
MATLAB 5.2のように、MATLABは左辺のリスト(plhs[]
)に出力されない任意のmxArray
においてMEX-ファイルの実行の最後にmxArray
のデストラクタmxDestroyArray
を暗示的に呼び出します。MATLABが誤って作成されたあるいは不適切に破棄されたmxArray
を検出した場合、ワーニングを発生します。
つぎの節で説明するワーニングを生成するMEX-ファイルのコードを修正することを強く推奨します。詳細は、「C言語MEX-ファイルの作成」の「メモリ管理」を参照してください。 .
注意 現時点では、下記のワーニングは、下位互換性の理由により デフォルトで利用可能です。将来のMATLABのリリースでは、このワーニングは、デフォルトで利用不可能になる予定です。プログラマは、MEX-ファイルの開発サイクルにおいて、これらのワーニングを利用可能にする必要があります。 |
不適切にmxArrayを破棄する
mxFree
を使ってmxArray
を破棄することはできません。
Warning: You are attempting to call mxFree on a <class-id> array. The destructor for mxArrays is mxDestroyArray; please call this instead. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
つぎの例題では、mxFree
は配列オブジェクトを破棄しません。このオペレーションは、配列に関連する構造体のヘッダを開放しますが、MATLABは配列オブジェクトを破棄する必要があるかのように機能します。そのため、MATLABは配列オブジェクトを破棄しようとし、さらにそのプロセスで再度構造体のヘッダを開放しようとします。
mxArray *temp = mxCreateDoubleMatrix(1,1,mxREAL); ... mxFree(temp); /* INCORRECT */
mxDestroyArray(temp); /* CORRECT */
セルまたは構造体のmxArrayを不適切に作成
mxSetCell
またはmxSetField
をprhs[]
によってメンバ配列として呼び出すことはできません。
Warning: You are attempting to use an array from another scope (most likely an input argument) as a member of a cell array or structure. You need to make a copy of the array first. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
つぎの例で、MEX-ファイルがリターンするとき、MATLABはセル配列全体を破棄します。これは、セルのメンバを含むので、MEX-ファイルの入力引数を暗示的に破棄します。これにより、右辺引数がテンポラリ配列である(リテラルの、または式の結果)場合、通常呼び出し側のワークスペースの破棄に関連する奇妙な結果が生じる場合があります。
myfunction('
hello'
) /* myfunction is the name of your MEX-file and your code */ /* contains the following: */ mxArray *temp = mxCreateCellMatrix(1,1); ... mxSetCell(temp, 0, prhs[0]); /* INCORRECT */
mxDuplicateArray
を使って右辺引数のコピーを作り、そのコピーをmxSetCell
(またはmxSetField
の引数として使います。たとえば、
mxSetCell(temp, 0, mxDuplicateArray(prhs[0])); /* CORRECT */
テンポラリなmxArrayを不適切なデータで作成
APIルーチンによって割り当てられていないデータをもつmxArray
についてmxDestroyArray
を呼び出すことはできません。
Warning: You have attempted to point the data of an array to a block of memory not allocated through the MATLAB API. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
mxSetPr
, mxSetPi
, mxSetData
, mxSetImagData
を呼び出し、mxCalloc
, mxMalloc
, mxRealloc
によって割り当てられていないメモリをデータブロック(第二引数)として指定する場合、MEX-ファイルがリターンするとき、MATLABは実数データのポインタと虚数データ(存在すれば)のポインタを開放しようとします。そのため、MATLABは、この例ではプログラムスタックからメモリを開放しようとします。これにより、MATLABが互換性のチェックの情報を一致させようとするときに、上記のワーニングを発生します。
mxArray *temp = mxCreateDoubleMatrix(0,0,mxREAL); double data[5] = {1,2,3,4,5}; ... mxSetM(temp,1); mxSetN(temp,5); mxSetPr(temp, data); /* INCORRECT */
データポインタを設定するためにmxSetPr
を使うよりも、正しいサイズでmxArray
を作成し、memcpy
を使ってスタックデータをmxGetPr
によって出力されるバッファにコピーします。
mxArray *temp = mxCreateDoubleMatrix(1,5,mxREAL); double data[5] = {1,2,3,4,5}; ... memcpy(mxGetPr(temp), data, 5*sizeof(double)); /* CORRECT */
潜在的なメモリリーク
バージョン5.2以前は、API作成ルーチンを使ってmxArray
を作成し、mxSetPr
を使ってデータのポインタを上書きする場合には、MATLABはオリジナルのメモリを開放していました。これは現在は行われません。
pr = mxCalloc(5*5, sizeof(double)); ... <load data into pr> plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL); mxSetPr(plhs[0], pr); /* INCORRECT */
は、メモリが5*5*8バイトリークします。ここで、8バイトはdouble
のサイズです。
plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL); pr = mxGetPr(plhs[0]); ... <load data into pr>
pr = mxCalloc(5*5, sizeof(double)); ... <load data into pr> plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL); mxFree(mxGetPr(plhs[0])); mxSetPr(plhs[0], pr);
同様のメモリリークは、mxSetPi
, mxSetData
, mxSetImagData
, mxSetIr
, mxSetJc
を使ったときにも起こる場合があります。メモリリークを防ぐために、上記のようにこの問題に対応することができます。
MEX-ファイルは、自身のテンポラリ配列を破棄します
一般に、MEX-ファイルがテンポラリ配列を破棄し、テンポラリメモリをクリーンアップすることを推奨します。左辺のリストに出力されるものとmexGetArrayPtr
によって出力するもの以外のすべてのmxArray
は、安全に破棄されます。この方法は、他のMATLAB APIアプリケーションとの整合性があります(例, 自動クリーンアップメカニズムをもたないMAT-ファイルアプリケーション、エンジンアプリケーション、MATLAB Compiler生成アプリケーション)。
![]() | コンパイラとプラットフォーム固有の問題 | その他の情報 | ![]() |