Hi,
I am new to writing mex files. I tried writing one and
it is running. It has two parametrs (a file name, and a double value), one inport and no outport. The purpose of the mexfile is writing to a file in ascii and doing some small calculations before writing to the file.
The mex file is executed many time (e.g. 100000) in a row. It seems that the execution somehow consumes memory. I do not now where and how I should "free" memory in my mex file. Any help on that would be great! The problem is that matlab crashes because it can not allocate more memory!
This is the code. I started by adapting code from a tamplate. So most of it is not my own code.....
-----------------------------------------------------
#define S_FUNCTION_NAME sfun_textOutput /*Name of the S-function file*/
#define S_FUNCTION_LEVEL 2 /*Level 2 S-functions allow multi-port status*/
#include "simstruc.h" /*Header where different routines are defined */
#include <stdio.h> /*added so in/out rountines work correctly*/
#define MYFILEPR my_file_pointer_file /*Define variable representing actually file pointer name */
FILE *MYFILEPR; /*Declare file pointer to a file */
int previouslyFailedTestStep_1 = -1; /*only write to the file if the next failure is different from the previous*/
int previouslyFailedTestStep_2 = -1; /*only write to the file if the next failure is different from the one before previous*/
int previouslyFailedTestStep_3 = -1; /*only write to the file if the next failure is different from the one before before the previous*/
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* Setup the various initial conditions necessary to run the S-functions.
*/
static void mdlInitializeSizes(SimStruct *S)
{
/*We have two Additional Parameter in this S-function.
* 1) the file name where the results are written to
* 2) delta t of the test case */
ssSetNumSFcnParams(S, 2);
/* Parameter mismatch will be reported by Simulink */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
/*get the filename parameter*/
char filename[128];
mxGetString(ssGetSFcnParam(S, 0), filename, 128);
/* Opens a file, whose name is contained in filename, for writing */
MYFILEPR=fopen(filename,"w");
/*We define one input and no output port here*/
ssSetNumInputPorts(S, 1);
ssSetNumOutputPorts(S,0);
{
/*Here we say that we expect a scalar input
*for the port. We could use the macro
*DYNAMICALLY_SIZED like in the example timestwo.c to allow vector inputs
*and outputs. */
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortDirectFeedThrough(S, 0, 1);
}
ssSetNumSampleTimes(S, 1);
/* Take care when specifying exception free code - see sfuntmpl.doc */
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* Specifiy that we inherit our sample time from the driving block.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
/* Function: mdlOutputs =======================================================
* Abstract:
*
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
/*In mdlOutputs is where the real "meat" of our S-function comes in
*
*Here we use the ss* macros(found in the S-function documentation) to
*get a pointer to the Input Signal. The first input
*S is the Simstruct and is required, the second input is the port number
*we are manipulating.
*/
/*The current value at the first inputport*/
InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,0);
/*get the delta t parameter*/
double deltaT;
deltaT = (double)(mxGetScalar(ssGetSFcnParam(S, 1)));
/*only write to the file if there was an error reported in the test case*/
if(*uPtrs1[0]!=(-1)){
/*the reported time of the error diveded by delta t incremented by one and converted to an int*/
/*e.g. 5 = 2.1/0.5 +1 ==> [0,0.5);[0.5,1);[1,1.5);[1.5,2);[2,2.5);[2.5,3);...*/
/* Intervall: 1 2 3 4 5 6; ...*/
int testStep = (int)((*uPtrs1[0])/deltaT)+1;
/*reduce the amount of entries in the file*/
if((testStep != previouslyFailedTestStep_1)&&(testStep != previouslyFailedTestStep_2)&&(testStep != previouslyFailedTestStep_3)){
previouslyFailedTestStep_3=previouslyFailedTestStep_2;
previouslyFailedTestStep_2=previouslyFailedTestStep_1;
previouslyFailedTestStep_1=testStep;
fprintf(MYFILEPR,"%i\n", testStep);
}
}
}
/* Function: mdlTerminate =====================================================
* Abstract:
* No termination needed, but we are required to have this routine.
*/
static void mdlTerminate(SimStruct *S)
{
fclose(MYFILEPR); /*Closes the file, MYFILEPR */
}
/*End of file necessary includes*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif