MexFile 导致“检测到断言”错误 - mexfiles 中的 memcpy 出现问题?
不幸的是,这个问题很狭窄,但我不知所措。
我有一个自定义 mex 文件,它采用两个 uint32 列表,每个列表都已排序且不包含公共条目,并返回一个包含两个列表中所有条目的排序列表。代码是:
#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 文件的代码时,我收到断言检测到的错误(例如 Found Corrupted block 381 in table 5. (invalid table index). )。断言总是会出现,但不一定出现在同一个地方。
如果我恢复到旧版本的代码,就没有问题。所以有些东西正在破坏记忆,但我看不到它。我所做的更改之一是使用 memcpy,但看不出有什么问题。
再次,我很抱歉这是一个如此狭窄的问题,但我们将不胜感激。
更新:肯定是 memcpy 导致了断言。如果我恢复在循环中赋值,断言就会停止。在 mex 文件中使用 memcpy 有限制吗?
This problem is unfortunately narrow, but I'm at a loss.
I have a custom mex file that takes two lists of uint32s that are each sorted and contain no common entries and returns a single sorted list containing all of the entries from both list. The code is:
#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;
}
When I run code that calls the mex file, I get assertion detected errors (with stuff like Found corrupted block 381 in table 5. (invalid table index). ). The assertions always arise, but not necessarily at the same place.
If I revert to the old version of the code, there are no problems. So something is mangling memory, but I can't see it. One of the changes I made is to use memcpy, but can't see anything wrong there.
Again, I'm sorry that this is such a narrow question, but any help would be appreciated.
UPDATE: It is definitely the memcpy that is causing the assertion. If I revert to assigning values in a loop, the assertions stop. Are there restrictions with using memcpy in mex-files?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我重写了 CalculationRoutine 函数,如下所示:
以下是我测试其正确性/性能的方法:
计时为:
I rewrote the
CalculationRoutine
function as follows:And here is how I tested its correctness/performance:
The timings were:
这是 memcpy 的第三个参数中的一个差一错误。 while 循环应该是:
It's an off-by-one error in the third argument to memcpy. The while loop should be: