この問題は残念ながら狭いですが、途方に暮れています。
それぞれが並べ替えられ、共通のエントリを含まない uint32 の 2 つのリストを取得し、両方のリストのすべてのエントリを含む単一の並べ替えられたリストを返すカスタム mex ファイルがあります。コードは次のとおりです。
#include "mex.h"
#include "matrix.h"
#include "string.h"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
void CalculationRoutine(uint32_T* CombinedList, const mwIndex FirstNumels, uint32_T* FirstList, const mwIndex SecondNumels, uint32_T* SecondList) {
mwIndex OutCounter = 0, FirstCounter = 0, SecondCounter = 0;
unsigned int i;
// Short-circuit if there is no ovelap.
if (*FirstList > *(SecondList+SecondNumels-1)) {
memcpy(CombinedList,SecondList,SecondNumels*sizeof(uint32_T));
memcpy(CombinedList+SecondNumels,FirstList,FirstNumels*sizeof(uint32_T));
return;
} else if (*SecondList > *(FirstList+FirstNumels-1)) {
memcpy(CombinedList,FirstList,FirstNumels*sizeof(uint32_T));
memcpy(CombinedList+FirstNumels,SecondList,SecondNumels*sizeof(uint32_T));
return;
}
// These can be done with no exhaustion checking. Leave one item because we
// are doing post-checking in the second loop.
for (i=MIN(FirstNumels, SecondNumels)-1; i--;) {
if (*(FirstList+FirstCounter) < *(SecondList + SecondCounter)) {
*(CombinedList+OutCounter) = *(FirstList+FirstCounter);
FirstCounter++;
} else {
*(CombinedList+OutCounter) = *(SecondList+SecondCounter);
SecondCounter++;
}
OutCounter++;
}
// These ones need exhaustion checking.
while (1){
if (*(FirstList+FirstCounter) < *(SecondList + SecondCounter)) {
*(CombinedList+OutCounter) = *(FirstList+FirstCounter);
FirstCounter++;
if (FirstCounter == FirstNumels) {
// Just copy the rest of the second list.
memcpy(CombinedList+OutCounter+1,SecondList+SecondCounter,(SecondNumels-SecondCounter+1)*sizeof(uint32_T));
return;
}
} else {
*(CombinedList+OutCounter) = *(SecondList+SecondCounter);
SecondCounter++;
if (SecondCounter == SecondNumels) {
// Just copy the rest of the first list.
memcpy(CombinedList+OutCounter+1,FirstList+FirstCounter,(FirstNumels-FirstCounter+1)*sizeof(uint32_T));
return;
}
}
OutCounter++;
}
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
mxArray *CombinedList = NULL;
uint32_T *FirstList, *SecondList;
mwIndex FirstNumels = mxGetNumberOfElements(prhs[0]), SecondNumels = mxGetNumberOfElements(prhs[1]);
//Input Checking
if (!mxIsUint32(prhs[0])) {
mexErrMsgTxt("FirstList must be matrix of uint32.");
}
if (!mxIsUint32(prhs[1])) {
mexErrMsgTxt("SecondList must be a matrix of uint32.");
}
CombinedList = mxCreateNumericMatrix(FirstNumels+SecondNumels, 1, mxUINT32_CLASS, mxREAL);
if (CombinedList == NULL) {
mexErrMsgTxt("SecondList must be a matrix of uint32.");
}
//Short circuit when we have one or the other inputs empty.
if (mxIsEmpty(prhs[0])){
if (!mxIsEmpty(prhs[1])) {
// Return the SecondList verbatim.
//CopyOneInput(mxGetData(CombinedList),SecondNumels, mxGetData(prhs[1]));
memcpy(mxGetData(CombinedList), mxGetData(prhs[1]),SecondNumels*sizeof(uint32_T));
}
plhs[0] = CombinedList;
return;
} else if (mxIsEmpty(prhs[1])) {
// Return the FirstList verbatim.
//CopyOneInput(mxGetData(CombinedList),FirstNumels, mxGetData(prhs[0]));
memcpy(mxGetData(CombinedList), mxGetData(prhs[0]),FirstNumels*sizeof(uint32_T));
plhs[0] = CombinedList;
return;
}
CalculationRoutine(mxGetData(CombinedList),FirstNumels,
mxGetData(prhs[0]),SecondNumels,mxGetData(prhs[1]));
plhs[0] = CombinedList;
}
mex ファイルを呼び出すコードを実行すると、アサーション検出エラーが発生します (テーブル 5 の壊れたブロック 381 が見つかりました。 (無効なテーブル インデックス) など)。アサーションは常に発生しますが、必ずしも同じ場所ではありません。
古いバージョンのコードに戻せば、問題はありません。何かがメモリを壊していますが、私には見えません。私が行った変更の 1 つは memcpy を使用することですが、そこには何も問題はありません。
繰り返しますが、これは非常に狭い質問で申し訳ありませんが、助けていただければ幸いです。
更新: アサーションを引き起こしているのは間違いなく memcpy です。ループで値の割り当てに戻ると、アサーションが停止します。mex ファイルで memcpy を使用する際に制限はありますか?