A comment on the use case: I have a long string and I'd like to take parts of that long string and dole it out to substrings for struct entries.
mxSetData to subset of mxArray
조회 수: 1 (최근 30일)
이전 댓글 표시
Is it possible, perhaps with a certain set of restrictions on what the user can do, to assign data to an mxArray which is a subset of some memory that has already been allocated?
채택된 답변
James Tursa
2016년 11월 26일
Not without a hack. The reason is as follows:
The API functions mxSetPr, mxSetPi, mxSetData, mxSetImagData, mxSetIr, and mxSetJc etc all check to see if the pointer passed in for the data memory is from the MATLAB Memory Manger allocation list. If it isn't, then the mex routine will crash MATLAB with an assertion fault. In practical terms, this means that you need to individually allocate each memory block using MATLAB API functions ... you can't allocate one big block and then piece it out to multiple mxArray's, and you can't use C native allocated memory either (e.g., can't use malloc and friends).(*)
So, the only way to attach such memory to the data area of an mxArray is to hack into the mxArray structure itself and set the desired pointer manually. But this leaves you in a precarious state, because if MATLAB ever tried to destroy this mxArray (e.g., maybe there is an error return from your mex routine and garbage collection takes place) then MATLAB would crash when it tried to free this memory. So you could do some things with it (e.g., as an input to mexCallMATLAB where you knew the function you were calling would not make a shared data copy of the input). But to be safe you would probably need to protect this mxArray from being garbage collected (i.e., make it persistent and set up a mexAtExit function to clean things up properly), and you would need a way for the mex routine to safely detach the data pointers before this mxArray gets destroyed. Bottom line is that doing this is possible, but very tricky to get things set up so that MATLAB does not crash ... and it requires a lot of hacks.
(*) Note: Earlier versions of MATLAB did not make these checks, so you could get away with using the API functions to set the data pointers with non-MATLAB allocated memory. But you would still be faced with a potential crash if MATLAB ever tried to destroy this mxArray while it was in the invalid state.
댓글 수: 2
James Tursa
2016년 11월 26일
"... I don't see any way to know when 'a' finally becomes the last 'a' ..."
You could create a shared data copy of "a", make it persistent, and keep it inside the mex routine with the mex routine locked with mexLock(). MATLAB would not be able to destroy this mxArray because it isn't on the garbage collection list and is not in any workspace either. Destroying it would be part of a mexAtExit procedure, but it would only be destroyed if there were no other shared data copies (detectable from the CrossLink field of the mxArray structure), no other reference copies (detectable from the refCount field of the mxArray structure), and no other subset copies (detectable some TBD way) in existence. That last part would be very tricky ... I don't have any suggestion for that yet (other than being part of some OOP class).
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!