Fundamental Principle: You cannot mix native Fortran (or C or C++) memory within an mxArray. To do so will always result in a crash. You can only use MATLAB API function allocated memory within an mxArray. And even then, you must know what you are doing to make sure the memory is accounted for properly in the MATLAB Memory Manager so it doesn't inadvertantly free memory that is part of an mxArray, which would result in a crash.
To fix your immediate problem, note that you have used a pointer to an mxArray (the result of your mxCreateDoubleMatrix call) as a pointer to a real(8) data block. That results in writing over the mxArray structure itself in the very next line with the mxCopyReal8ToPtr call, leading to the crash. To fix that, change this line:
something = mxCreateDoubleMatrix(num_i4, num_i4, 0)
to this:
something = mxMalloc( 8 * num_i4 * num_i4 )
At that point in the code, the "something" address will be on the garbage collection list (i.e., scheduled to be free'd as soon as the mex function returns control to the caller).
Your attempt at using "something" will also cause a crash, however:
call mxSetPr(plhs(1), something)
You haven't created plhs(1) yet, so it is pointing to garbage at this point. Using it in an API call will result in a crash. To do what you are trying to do, you would need to do this:
mwSize :: num_i4, zero = 0
integer(4) :: mxREAL = 0
plhs(1) = mxCreateDoubleMatrix(zero,zero,mxREAL)
:
call mxSetPr(plhs(1),something) ! removes something from garbage collection list
call mxSetM(plhs(1),num_i4)
call mxSetN(plhs(1),num_i4)
All of the above is the hard way of doing things, however. A simpler approach is to simply use mxCreateDoubleMatrix in the calling routine to the desired size to begin with, then pass its data pointer down to the computational routine. E.g.,
mwSize :: num_i4
integer(4) :: mxREAL = 0
:
plhs(1) = mxCreateDoubleMatrix(num_i4,num_i4,mxREAL)
something = mxGetPr(plhs(1))
:
call make_matrix(
:
real*8 :: something(num_i4,num_i4)
Side Comment: You should really make the check "nlhs .ne. nargout" as "nlhs .gt. nargout" instead. The way you have it, you are not allowing the user to return the result into ans, but are forcing him/her to assign the result into a variable. That is generally too restrictive and is not how users expect most functions to operate.
Best Answer