Need help on assigning output arguments in C language
Show older comments
Hi all,
I have a simple function written in C, which I've been using as a MEX. In the earlier versions of Matlab, it has been working ok, but the current release (and couple of earlier ones) crashes eventually when attempting to run the code. By compiling the C into a MEX in a current release, and then running it, gives out the error "one or more output arguments not assigned...". So, a simple problem it seems, but I'm not that familiar with C, so any help is much appreciated.
Below is a screenshot showing how I'm able to run the old MEX in a current release couple of times until Matlab eventually crashes:

The function "generateRandSumc" returns a vector of random integers, where the length of the vector is the first argument (15 in the example), and the sum of the vector is the second argument (48).
Below is a second screenshot that shows how the current release can detect the missing output arguments after the MEX compilation:

And finally, here is the C-code: (sorry for the not-so-good-structuring)
#include "mex.h"
#include "matrix.h"
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// random number sequence picked from 1:k, of size n
void randpermc(mwSize N, mwSize k, double *p)
{
// N is the max range of the results in the array
// k is the length of the array
// i.e., select k values in the range 1:N
mwIndex i;
int randNo;
int *haveRand; // pointer to haveRand
haveRand=malloc(sizeof(int) * N); // allocate memory to haveRand
for(i=0; i<=N; i++)
haveRand[i] = 0; // initialize array.
for(i=0; i<k; i++)
{
do
{
randNo = rand()%N +1;
} while ( haveRand[randNo] == 1 );
haveRand[randNo] = 1;
p[i]=randNo;
}
}
int cmp(const void *x, const void *y)
{
double xx = *(double*)x, yy = *(double*)y;
if (xx < yy) return -1;
if (xx > yy) return 1;
return 0;
}
// random number sequence picked from 1:n, of size k
void generateRandSumc(mwSize n, mwSize summ, double *p)
{
int i;
double pLength = sizeof(p)/sizeof(p[0]);
double *q;
q=malloc(sizeof(double) * n); // allocate memory
randpermc(n+summ-1,n-1,q);
qsort(q, n-1 ,sizeof(double), cmp);
for(i=0; i<n; i++)
{
if ( i == 0 ) {
p[i]=q[i]-1; }
else if ( i == n-1 ) {
p[i]=n+summ-q[i-1]-1 ; } // add endpoint
else {
p[i]=q[i]-q[i-1]-1 ;
}
}
}
}
I hope this makes some sense
Thanks, Tero
6 Comments
The code has no valid C syntax. You cannot define a function inside another one:
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// random number sequence picked from 1:k, of size n
void randpermc(mwSize N, mwSize k, double *p)
{
...
Where are the prototypes for the functions randpermc and generateRandSumc?
Does MinGW really compile the posted code successfully? I cannot imagine this.
You are mixing int, mwSize and mwIndex freely. This is a bad idea. pLength is defined, but never used.
This is a bad idea:
randNo = rand()%N +1;
It is not an error, but the result is biased: This does not create an even distribution.
A proper indentation of the code lines would be a good idea, because it improves the readability of the code. If you are not familiar with C, I strongly recommend to implement this in Matlab.
Tero
on 13 Jun 2018
Steven Lord
on 13 Jun 2018
Why not just use the MATLAB code? Why do you feel it's necessary to convert that into a MEX-file?
James Tursa
on 13 Jun 2018
Edited: James Tursa
on 13 Jun 2018
Can you re-post your current code? It is indeed quite strange that MinGW compiles the posted code above when MSVC shows numerous errors. Apparently MinGW allows function definitions inside of other functions. In your above posted code, there is no body to the mexFunction so no plhs[] variables are produced, hence the error when calling it and assigning an output.
OCDER
on 13 Jun 2018
Also, there is no reference to plhs[x], which means no output was ever assigned. A word search in the code never finds plhs besides in the mexFunction gateway.
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
//ERROR: No use of plhs! No output was assigned to this function.
//WARNING: No use of prhs! No input is needed or referred to in this function
}
In addition to the problems pointed out by Jan, I'm fairly certain that:
double pLength = sizeof(p)/sizeof(p[0]);
is wrong. That syntax only works when p is an array, not a pointer. There is no way to retrieve the size of the original array from within generateRandSumc. It needs to passed as an argument. Thankfully, pLength is never used so the incorrect calculation doesn't matter. As it is pLength will always be 1 on a 64-bit machine.
If mex generateRandSumc.c compiles succesfully, there's no way that it's compiling the code posted above. It must be compiling a different file in another location. One that is at least valid C.
As Steven says, why bother with the mex code if you've got working matlab code. At least, the matlab code is reliable and does not have the bias exhibited by the C code.
Accepted Answer
More Answers (1)
Tero
on 13 Jun 2018
0 votes
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!