problems declaring static in Mex?

조회 수: 4 (최근 30일)
gujax
gujax 2012년 3월 17일
I am having lot of trouble with C and Mex issues. I think it stems from not having a clear concept of C/C++.
I am generating a data y from y=f(A,t). y and t are arrays. A is a single scalar. This function gets called many times in a run.
t value does not change but A value keeps changing dynamically between each call to my_fun =f
I do not want to generate the data t for every run and I tried it this way and it did not work. Here is an example slightly modified from Matlab's own (just for demo).
void timestwo(double A, double *y, double *x)
{
static double *t;
static int count;
int i,j;
if count == 0
{ for i=0;i<80;i++
{t = i;
y[i]=A*t[i];
}
}
count = count+1;
x=t;
printf("%i",count);
printf("%f",x[50]);
return
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x, A, *y;
A = mxGetScalar(prhs[0]);
plhs[0] =mxCreateDoubleMatrix(256,1,mxReal);
y=mxGetPr(plhs[0]);
plhs[1] =mxCreateDoubleMatrix(256,1,mxReal);
x=mxGetPr(plhs[1]);
timestwo(&A,y,x);
return
}
This does not work.(I may have made a mistake coding for A above because I am writing off my head from memory);
>[A,B]=timestwo(1);
>1
>50.0
>A
prints out 1:80
>B
prints out 80 zeros;
>[A,B]=timestwo(3);
>2
>150.0
>[A B]
B prints out correct but A's are all zero.
In every run B comes out correct but not A.
I tried replacing the statement x=t in the function with *x=*t, or
memcpy(x,t,80), or
x=&t[0];
But none work.
Strange!, some funky thing with pointers not getting initialized? How can I use static? My own program is pretty complicated and I do not want to generate t every time. But I have to use t to get y and this involves countless loops. I can generate t in my Matlab space and keep sending it to mex routine - but on principle, why does this not work?
  댓글 수: 5
gujax
gujax 2012년 3월 18일
Ok,
altered my question completely.
It looks readable now. Sorry about that.
Jan
Jan 2012년 3월 18일
"for i=0;i<80;i++" is no valid C code. You need more parenthesis.

댓글을 달려면 로그인하십시오.

채택된 답변

Friedrich
Friedrich 2012년 3월 18일
Hi,
your code looks pretty bad. Here is one way to do it:
#include "mex.h"
static double *t = NULL;
static int count = 0;
//we need to free the allocated memory, we do this when the mex file is
//released from memory
static void CleanUp(void)
{
mexPrintf("cleaning up\n");
//mxFree(t); this wont work
free(t);
count = 0;
}
void timestwo(double A, double *y, double *x)
{
int i,j;
//first call?
if (count == 0)
{
//if so allocate memory
//t = (double*) mxMalloc(80*sizeof(double)); wont work
t = (double*) malloc(80*sizeof(double));
for(i=0;i<80;i++)
{
//fill up t, which will never change
t[i] = (double) i;
//calculate y
y[i]=A*t[i];
}
}else
{
//timestwo was called before, so memory is allocated and t is filled,
//simple calaculte y again
for(i=0;i<80;i++)
y[i]=A*t[i];
}
count = count+1;
//copy the t vector into x
memcpy(x,t,80*sizeof(double));
mexPrintf("%i\n",count);
mexPrintf("%f\n",x[50]);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//first call?
if (t == NULL){
//if so set the cleanup routine
mexAtExit(CleanUp);
}
plhs[0] =mxCreateDoubleMatrix(80,1,mxREAL);
plhs[1] =mxCreateDoubleMatrix(80,1,mxREAL);
timestwo(mxGetScalar(prhs[0]),mxGetPr(plhs[0]),mxGetPr(plhs[1]));
}
  댓글 수: 3
gujax
gujax 2012년 3월 18일
Actually, when I run this program (Friedrich's copy-paste) it runs the first call well. From the second call every output is zero.
However, and this is very very strange...
clear mex;
and now everything runs fine. All subsequent calls provide me appropriate values of A and B.
i.e.
[A,B]=timestwo(1)
1
50.00
[A,B]=timestwo(2)
2
100.00
and so on..
But, when I close matlab and restart and try this program fresh I get the same problem - first call is good, next call onwards all 0. And this even after I begin new session i.e., after I restart Matlab and start with clear mex.
So there is still some bug and I feel it is now a Matlab bug!!?
Or some strange after effects in my computers memory sector?
Any ideas people?
Friedrich
Friedrich 2012년 3월 18일
Seems to be related to the ML memory Manager. use malloc instead mxMalloc and free instead of mxFree and it should work fine.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2012년 3월 18일
If you allocate memory using malloc() it is freed by free() only. If the free() is omitted, the array exists persistently. If the free() is forgotton, you have a memory leak.
In opposite to this mxMalloc is "smart": all reserved memory is released automatically when the mex function is left. To store the memory persistently use mexMakeMemoryPersistent().
Sometimes you can access the memory "successfully" if you only store the pointer to it persistently. But this works only until the memory is used for other values, and therefore this is a cause for not reproducible crashs.
  댓글 수: 4
James Tursa
James Tursa 2012년 3월 18일
P.S. A similar thing happens to mxArray variables created inside a mex routine with the mxCreateETC routines. They are all put on the garbage collection list. When the mex routine returns to MATLAB, the mxArray variables that are part of the plhs[0], plhs[1], etc are removed from the garbage collection list and are not free'd. Every other mxArray created in the mex routine *is* free'd unless you have specifically told MATLAB not to free it via a mexMakeArrayPersistent call.
James Tursa
James Tursa 2012년 3월 18일
See this thread for a thorough explanation of persistent memory and mxArrays:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/316593#866015

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by