Mex 文件仅在第二次使用时出现分段错误

发布于 2024-11-02 19:36:00 字数 2806 浏览 0 评论 0原文

以下代码在第一次调用时编译成功并返回正确的结果。第二次进行相同的调用时,我收到分段错误错误。

//% function TF = InWindow(Date,WindowStartDates,WindowEndDates,EndHint)
//% INWINDOW returns true for window that contains Date. All inputs must be 
//% uint32 and WindowEndDates must be sorted.

//% EndHint is an optional input that specifies the row number to start
//% searching from.

#include "mex.h"
#include "matrix.h"
#include "math.h"

void CalculationRoutine(mxLogical *ismember, uint32_T *Date, uint32_T *WindowStartDates, uint32_T *WindowEndDates, unsigned int *StartIndex, int NumObs) {

mwIndex Counter;

// Find the first window that ends on or after the date. 
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {  
    if (*Date <= *(WindowEndDates+Counter)) {
        break;
    }
}
*StartIndex = (unsigned int) Counter;

// Now flag every observation within the window. Remember that WindowStartDates
// is not necessarily sorted (but WindowEndDates is).
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) { 
    if (*Date >= *(WindowStartDates+Counter)) {
        *(ismember+Counter) = true;
    }
}

}

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {

    mxArray *ismember;
    unsigned int *StartIndex;

    //Input Checking.

    if (nrhs == 3) {
        // Default Hint to first entry.        
        mexPrintf("SI Starts OK.\n");
        *StartIndex = 1;
        mexPrintf("SI Ends OK.\n");
    } else if (nrhs == 4) {
        if (!mxIsUint32(prhs[3])) {
            mexErrMsgTxt("EndHint must be uint32.");
        } 
        StartIndex = mxGetData(prhs[3]);
    } else {
        mexErrMsgTxt("Must provide three or four input arguments.");
    }
    // Convert the hint to base-zero indexing.
    *StartIndex = *StartIndex - 1;

    // Check the inputs for the window range.
    if (!mxIsUint32(prhs[0])) {
        mexErrMsgTxt("DatesList must be uint32.");
    }
    if (!mxIsUint32(prhs[1])) {
        mexErrMsgTxt("WindowStartsDates must be uint32.");
    }
    if (!mxIsUint32(prhs[2])) {
        mexErrMsgTxt("WindowEndsDates must be uint32.");
    }

    if (mxGetM(prhs[1]) != mxGetM(prhs[2])) {
        mexErrMsgTxt("WindowStartDates must be the same length as WindowEndDates.");
    }    

    // Prepare the output array.
    ismember = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[1]), mxGetDimensions(prhs[1]));

    CalculationRoutine(mxGetLogicals(ismember),mxGetData(prhs[0]), 
        mxGetData(prhs[1]), mxGetData(prhs[2]), StartIndex, (int) mxGetM(prhs[1]));

    plhs[0] = ismember;
}

我这样调用它:

>>InWindow(uint32(5),uint32((1:6)'),uint32((3:8)'))

代码在分段错误之前到达两个 mexPrintf 调用之间的行(即第一个调用打印,但不是第二个调用)。

我使用的是Matlab 2007a(是的,我知道)、Win7 64位和VS 2008。

The following code compiles successfully and returns the correct results when called the first time. Making the same call a second time, I get a segmentation fault error.

//% function TF = InWindow(Date,WindowStartDates,WindowEndDates,EndHint)
//% INWINDOW returns true for window that contains Date. All inputs must be 
//% uint32 and WindowEndDates must be sorted.

//% EndHint is an optional input that specifies the row number to start
//% searching from.

#include "mex.h"
#include "matrix.h"
#include "math.h"

void CalculationRoutine(mxLogical *ismember, uint32_T *Date, uint32_T *WindowStartDates, uint32_T *WindowEndDates, unsigned int *StartIndex, int NumObs) {

mwIndex Counter;

// Find the first window that ends on or after the date. 
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {  
    if (*Date <= *(WindowEndDates+Counter)) {
        break;
    }
}
*StartIndex = (unsigned int) Counter;

// Now flag every observation within the window. Remember that WindowStartDates
// is not necessarily sorted (but WindowEndDates is).
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) { 
    if (*Date >= *(WindowStartDates+Counter)) {
        *(ismember+Counter) = true;
    }
}

}

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {

    mxArray *ismember;
    unsigned int *StartIndex;

    //Input Checking.

    if (nrhs == 3) {
        // Default Hint to first entry.        
        mexPrintf("SI Starts OK.\n");
        *StartIndex = 1;
        mexPrintf("SI Ends OK.\n");
    } else if (nrhs == 4) {
        if (!mxIsUint32(prhs[3])) {
            mexErrMsgTxt("EndHint must be uint32.");
        } 
        StartIndex = mxGetData(prhs[3]);
    } else {
        mexErrMsgTxt("Must provide three or four input arguments.");
    }
    // Convert the hint to base-zero indexing.
    *StartIndex = *StartIndex - 1;

    // Check the inputs for the window range.
    if (!mxIsUint32(prhs[0])) {
        mexErrMsgTxt("DatesList must be uint32.");
    }
    if (!mxIsUint32(prhs[1])) {
        mexErrMsgTxt("WindowStartsDates must be uint32.");
    }
    if (!mxIsUint32(prhs[2])) {
        mexErrMsgTxt("WindowEndsDates must be uint32.");
    }

    if (mxGetM(prhs[1]) != mxGetM(prhs[2])) {
        mexErrMsgTxt("WindowStartDates must be the same length as WindowEndDates.");
    }    

    // Prepare the output array.
    ismember = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[1]), mxGetDimensions(prhs[1]));

    CalculationRoutine(mxGetLogicals(ismember),mxGetData(prhs[0]), 
        mxGetData(prhs[1]), mxGetData(prhs[2]), StartIndex, (int) mxGetM(prhs[1]));

    plhs[0] = ismember;
}

I call it with:

>>InWindow(uint32(5),uint32((1:6)'),uint32((3:8)'))

The code reaches the line between the two mexPrintf calls before the segmentation fault (ie the first call prints, but not the second).

I am on Matlab 2007a (yes, I know), Win7 64bit and VS 2008.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森罗 2024-11-09 19:36:00

您需要初始化指针 StartIndex - 您很“幸运”它第一次工作,因为它没有指向定义的内存位置。为什么不做一些更像这样的事情:

unsigned int StartIndex;
// and either:
StartIndex = 1;
// or:
StartIndex = * (static_cast< unsigned int * >( mxGetData(prhs[3]) ) );

You need to initialize the pointer StartIndex - you're "lucky" that it works the first time, since it is not pointing to a defined memory location. Why not do something more like:

unsigned int StartIndex;
// and either:
StartIndex = 1;
// or:
StartIndex = * (static_cast< unsigned int * >( mxGetData(prhs[3]) ) );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文