| 外部インタフェース/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生成アプリケーション)。
| コンパイラとプラットフォーム固有の問題 | その他の情報 | ![]() |