matlab 数组范围内,数组 – 如何在MATLAB中识别数据存储在数组范围之外的位置?...

编辑:

As of Matlab 2015b,编码器现在有运行时错误检查作为一个选项(从Matlab发行说明):

In R2015b, generated standalone libraries and executables can detect and report run-time errors such as out-of-bounds array indexing. In

previous releases, only generated MEX detected and reported run-time

errors.

By default, run-time error detection is enabled for MEX. By

default, run-time error detection is disabled for standalone libraries

and executables.

To enable run-time error detection for standalone

libraries and executables:

At the command line, use the code

configuration property RuntimeChecks.

cfg = coder.config(‘lib’); % or

‘dll’ or ‘exe’

cfg.RuntimeChecks = true;

codegen -config cfg myfunction

Using the MATLAB Coder app, in the project build settings,

on the Debugging tab, select the Generate run-time error checks check

box.

The generated libraries and executables use fprintf to write

error messages to stderr and abort to terminate the application. If

fprintf and abort are not available, you must provide them. Error

messages are in English.

See 07001 and 07002.

原始答案:

关于声明从double子类化的注释中的答案,其中subsref方法过载以禁止生长将是一种很好的方法.

另一种简单的方法是在整个代码中(在每个循环迭代中或在函数的底部)撒取断言命令,以断言大小没有超过分配的大小.

例如,如果您的代码格式为:

x = zeros(a,1)

x(a+1) = 1

... lots of other operations

if coder.target('MATLAB')

assert(isequal(size(x), [a,1]), 'x has been indexed out of bounds')

end

如果分配了扩展数组的任何值,这将使断言失败.

为了使它更加整洁,你甚至可以创建一个边界检查所有你关心的变量的函数,再次包装coder.target if语句.然后你可以在整个代码中撒上这个.

它不像重载double类那样优雅,但另一方面它根本不会给编译代码增加任何开销.当溢出发生时,它也不会准确地给你错误,但它会让你相信代码在各种情况下运行良好.

您可以对分配更有信心的另一种方法是在可能适合的情况下对分配进行自己的检查.我在作业中看到的一个常见问题是这样的.我们有一个已分配的数组,并使用向量赋值从另一个数组中复制数据.例如,考虑以下情况:

t = char(zeros(5,7)); % Allocate a 5 by 7 char array

tempstring = 'hello to anyone'; % Here's a string we want to put into it.

t(1, 1:numel(tempstring)) = tempstring; % A valid assignment in MATLAB

>> size(t)

ans =

5 15

哦,哦,你在问题中关注的确切地说:t数组在分配期间已自动调整大小,在MATLAB中有效,但在Coder中创建的代码会导致段错误或MEX错误.另一种方法是使用end函数的强大功能来保持赋值整齐(但是被截断).如果我们将赋值更改为:

t(1,1:min(end,numel(tempstring))) = tempstring(1:size(t, 2));

t的大小将保持不变,但分配将被截断. end的使用允许在赋值期间进行边界检查.在某些情况下,这可能是处理问题的一种很好的方法,并且可以让您确信永远不会超出界限,但显然在某些情况下这是非常不合需要的(并且不会在MATLAB中给出错误消息.)

MATLAB提供的另一个有用的工具是编辑器本身.如果在代码中使用%#codegen标记,它将通知编辑器的语法检查器以突出显示各种代码生成问题,包括通过索引显然增加数组大小的位置.这无法抓住每一种情况,但这是一个很好的帮助.

最后一点.正如问题中所提到的,Coder生成的MEX文件会在分配时给出“索引超出矩阵维度”错误,并且会正常退出,甚至会告诉您发生错误的原始代码行.从Coder生成的C库没有这样好的行为或边界检查,并且在没有诊断的情况下将完全分段.中间答案是完成您正在做的事情,即将代码作为MEX运行.这对你的问题没有多大帮助(正如你所说的那样,重建MEX可能需要时间),但对于我们这些编写外部C代码的冷酷世界的人来说,能够运行MEX找到的中间测试这些错误是救命稻草.

底线是这是MATLAB和Coder生成的C代码之间的行为差​​异,它可能是重大问题的根源.在我自己的代码中,出于这个原因,我对数组访问和增长非常小心.这是我希望看到Coder工具本身有所改进的领域,但在编写针对Coder的MATLAB代码时,有一些方法要非常小心.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值