You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran移动平均子程序类型判定及调用越界问题咨询

移动平均类型判定及调用代码的越界问题分析

一、判定移动平均类型

咱们先直接给出结论:这个ma子程序实现的是滞后移动平均(trailing moving average),理由如下:

先看修正语法后的核心代码(原代码的{}替换为Fortran标准的then/end if):

subroutine ma(x, n, len, ave)
    integer n, len, i, j, k, m, newn
    real x(n), ave(n), flen, v
    newn = n-len+1
    flen = float(len)
    v = 0.0
    ! get the first average
    do i = 1,len
        v = v+x(i)
    end do
    ave(1) = v/flen
    if (newn>1) then
        k = len
        m = 0
        do j = 2, newn
            ! window down the array
            k = k+1
            m = m+1
            v = v-x(m)+x(k)
            ave(j) = v/flen
        end do
    end if
    return
end

从计算逻辑拆解:

  • 第一个输出值ave(1)是用输入数组x的前len个元素(x(1)到x(len))计算得到的,对应窗口结束在x(len)的位置;
  • 后续的ave(j)(j从2到newn)每次把窗口向右滑动一位:去掉窗口最左侧的旧值x(m),加入窗口右侧的新值x(k),最终ave(j)对应的是x(j)到x(j+len-1)的平均。

所有计算都只用到当前点及之前的元素,完全没有包含任何未来的点,既不符合居中移动平均(需要当前点前后元素)的逻辑,也和超前移动平均(依赖未来点)无关,完全符合滞后移动平均的定义。

二、调用代码的数组越界问题

再来看fts子程序的调用逻辑:

subroutine fts(x,n,np,trend,work)
    integer n, np
    real x(n), trend(n), work(n)
    call ma(x,n,np,trend)
    call ma(trend,n-np+1,np,work)
    call ma(work,n-2*np+2,3,trend)
return
end

根据补充说明,调用ma时传入的数组x实际长度是n-2*np,但ma子程序的计算会直接访问到x(n)的位置,必然触发越界:

以第一次调用ma(x,n,np,trend)为例,ma里的newn = n - np +1,第二个循环中k的最终值是len + (newn -1) = np + (n - np +1 -1) = n,但x的实际长度只有n-2*np(显然n > n-2*np,因为np是正整数),当k超过n-2*np时,就会访问到x数组的越界位置,引发内存访问错误。

举个具体例子:如果n=10,np=2,那么x的实际长度是10-2*2=6,但ma里会尝试访问x(10),这显然超出了x的合法范围。

内容的提问来源于stack exchange,提问作者A0A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:38:09