4 views (last 30 days)

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?

Friedrich
on 18 Mar 2012

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]));

}

Friedrich
on 18 Mar 2012

Jan
on 18 Mar 2012

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.

James Tursa
on 18 Mar 2012

What is happening is this:

t = (double*) mxMalloc(80*sizeof(double)); // wont work

The above statement allocates a memory block to hold 80 doubles, AND it puts the address of that block onto the garbage collection list. As soon as the mex file returns back to MATLAB, this memory is free'd and becomes invalid. Other code can overwrite it with anything. On the next (and all subsequent) calls to the mex routine, each time you access t you are accessing invalid memory because it has already been free'd. As Jan suggests, what you need to do is this:

t = (double*) mxMalloc(80*sizeof(double));

mexMakeMemoryPersistent(t);

The mexMakeMemoryPersistent call removes the address contained in t from the garbage collection list so that MATLAB will not free it when the mex routine returns to MATLAB. In conjunction with this you need to have your own clean-up routine to manually free it .. i.e. your mxFree(t) inside your CleanUp routine.

James Tursa
on 18 Mar 2012

James Tursa
on 18 Mar 2012

See this thread for a thorough explanation of persistent memory and mxArrays:

http://www.mathworks.com/matlabcentral/newsreader/view_thread/316593#866015

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

Start Hunting!
## 5 Comments

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68760

⋮## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68760

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68761

⋮## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68761

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68769

⋮## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68769

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68798

⋮## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68798

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68830

⋮## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/32588-problems-declaring-static-in-mex#comment_68830

Sign in to comment.