I'm working with Matlab coder, using variable size variables pointed out with coder.varsize
. This causes some variables to be declared with the type emxArray_real_T
, be initialized with emxInit_real_t
, be used with appropriate calls to emxEnsureCapacity_real
, and finally be released with usage of emxFree_real_T
.
I have several functions in which this happens, but sometimes, for reasons I can't isolate well, the emxFree_real_T
operation causes the compiled executable to abort, showing a backtrace and a Memory Map which don't seem helpful to me. This can be guessed because it happens when a variable size array stops being used (hence can be de-allocated).
By manipulating the C code, I can tell that the errors occur precisely on the calls to emxFree_real_T
function. Commenting out those lines makes the generated code work fine. But this seems both unsafe and a no-solution for my problem.
Unfortunately, this error is hard to reproduce, so I could not come up with a minimum working example.
Is this a known bug? I'm I missing something regarding the usage of variable size arrays?
Matlab version is R2019a.
The problem can have several causes, and the investigation starting point is enabling the option cfg.RuntimeChecks
, as pointed out by @RyanLivingston. There are other steps suggested by MathWorks when debugging generated code.
In this case, the %#codegen
directive already forbids the user from allocating memory dynamically by increasing the size of an array with:
myArray(end+1) = rand();
However, if the code implements it as:
for i:1:a
myArray(i) = rand();
end
Then it may have no means to know that the parameter a
will surpass the size of myArray
, and at each step, it will not increase its size with emxEnsureCapacity
. Adding the cfg.RuntimeChecks
will create an exception handling case that will pinpoint this occurrence.
A solution for this, would be assigning a larger variable to myArray
, such as in:
myArray = zeros(a,1);
for i:1:a
myArray(i) = rand();
end
Even if myArray
had previously been defined with a a smaller size (but set to be variable in size with coder.varsize
), the increased capacity will be ensured and the loop can proceed.