cmatlabmatlab-coder

emxFree_real_T Causing Executable to Abort


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.


Solution

  • 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.