emxFree_real_T 导致可执行文件中止

emxFree_real_T Causing Executable to Abort

我正在使用 Matlab 编码器,使用 coder.varsize 指出的可变大小变量。这导致某些变量以 emxArray_real_T 类型声明,使用 emxInit_real_t 初始化,通过适当调用 emxEnsureCapacity_real 使用,最后使用 emxFree_real_T 释放。

我有几个函数会发生这种情况,但有时,由于我无法很好地隔离的原因,emxFree_real_T 操作会导致编译的可执行文件中止,显示回溯和内存映射对我似乎没有帮助。这可以被猜到,因为它发生在可变大小数组停止使用时(因此可以被取消分配)。

通过操作 C 代码,我可以看出错误恰好发生在对 emxFree_real_T 函数的调用上。注释掉这些行可以使生成的代码正常工作。但这似乎既不安全又无法解决我的问题。

不幸的是,这个错误很难重现,所以我无法想出一个最低限度的工作示例。

这是一个已知错误吗?关于可变大小数组的使用,我遗漏了什么?

Matlab版本为R2019a

问题可能有多种原因,调查的起点是启用选项 cfg.RuntimeChecks,正如@RyanLivingston 所指出的。调试生成的代码时还有其他步骤 suggested by MathWorks

在这种情况下,%#codegen 指令已经禁止用户通过增加数组的大小来动态分配内存:

myArray(end+1) = rand();

但是,如果代码将其实现为:

for i:1:a
    myArray(i) = rand();
end

那么它可能没有办法知道参数a会超过myArray的大小,并且在每一步中,它不会增加emxEnsureCapacity的大小。添加 cfg.RuntimeChecks 将创建一个异常处理案例来查明此事件。

解决此问题的方法是为 myArray 分配一个更大的变量,例如:

myArray = zeros(a,1); 
for i:1:a
    myArray(i) = rand();
end

即使之前myArray定义了较小的尺寸(但coder.varsize设置为可变尺寸),增加的容量将得到保证并且循环可以继续。