The reason this crashes is because you have created a copy of an mxArray variable without telling the MATLAB Memory Manager that you did so. So when MATLAB subsequently clears one of these it invalidates the other, and then when MATLAB tries to use or clear the other it accesses invalid memory and crashes. I.e.,
The above gets the the mxArray pointer from prhs and assigns this exact pointer to plhs ... essentially a reference copy. So now there is an extra reference copy of prhs in the system but the MATLAB Memory Manager doesn't know about it. Eventually downstream in your code all of these copies get cleared, but on the next to last one MATLAB thinks all the copies are cleared so it releases the memory. Then when it tries to use or clear the last one it accesses invalid memory and crashes.
The same thing would happen if you tried to copy an mxArray pointer from one cell or struct array element into another element, either in the same or a different cell or struct array. This would in essence create a reference copy of the variable without telling the MATLAB Memory Manager about it. MATLAB will crash downstream at some point when these variables are cleared. This practice could be done safely if you were to bump up the reference count of the variable each time you made a new assignment, but this requires mxArray hacks because there is no API function to do this.
There are three ways to extract an mxArray variable from a cell or struct variable and assign it to a plhs[ ] variable. Assuming you have already checked that nrhs >= 1 and that mxGetField(prhs,0,"b") is not NULL:
1) The only official way, which creates a deep copy:
plhs = mxDuplicateArray(mxGetField(prhs,0,"b"));
This is the only method that is officially supported and will likely not break in the future. The downside is that if you are working with very large variables it can be a tremendous waste of time and memory to create this deep copy.
2) Using an unofficial API function to create a shared data copy:
plhs = mxCreateSharedDataCopy(mxGetField(prhs,0,"b"));
This method is very fast and is useful for large variables. But this method requires you to jump through some hoops, and it may break in the future if they remove this function from the API library. Details for using it can be found in the header file here:
3) Bump up the reference count:
plhs = mxCreateReference(mxGetField(prhs,0,"b"));
This method is also very fast and useful for large variables. This function used to be in the API library, and the only thing needed to use it was a prototype. However, this function was removed from the API library back in R2014a. So the only way to do this now is to hack into the mxArray itself. This is tricky to do since the mxArray definition and the location of the reference count field has changed over the years. Also the rules for how MATLAB handles the plhs[ ] variables are not published so it is unclear if this will even work for a sub-array type variable instead of a temporary variable. Although this would be the obvious method to use when copying cell or struct field variables from one cell or struct array to another cell or struct array, I wouldn't advise this option for assigning to the plhs[ ] array variables. I would advise method 2 instead for plhs[ ] array variable assignment.
Note that MATLAB itself generally uses either method 2 or 3 in the background when you are working at the m-file level, but for some reason has not made these methods official for mex programmers.