zoukankan      html  css  js  c++  java
  • Fortran程序调试中的“吐核”错误

    在CentOS7上安装了PGI编译器,但是调试过程中遇到的“段错误(吐核)”一直让人很头疼。

    通常采用在程序中增加屏幕输出代码的方式来追踪和定位出错的变量,比如下面这个样例程序就在第16行和第18行增加了两句输出:

     1    real*8, allocatable :: mlat(:),mlon(:)
     2    integer cnti,LenMLAT,LenMLON
     3    LenMLAT=50 4    LenMLON=30  5    if (.not.allocated(mlat)) allocate(mlat(LenMLAT)) 6    if (.not.allocated(mlon)) allocate(mlon(LenMLON)) 7    do cnti=0,LenMLAT-1
     8      mlat(cnti) = dble(cnti)
     9    enddo
    10 !  do cnti=1,LenMLAT
    11 !     write(*,'("mlat(",I2,"): ",F5.1)') cnti,mlat(cnti)
    12 !  enddo
    13 
    14 !......
    15 
    16    write(*,*) "@1338"
    17    if (allocated(mlat))   deallocate(mlat)
    18    write(*,*) "@1340"
    19    if (allocated(mlon))   deallocate(mlon)

    如果屏幕的输出内容停留在“@1338”,则表明它后面一句没有被成功执行,即: if (allocated(mlat)) deallocate(mlat) 失败。

    接下来,去程序中检查 $mlat 变量的定义和预分配部分,它必须具有可分配属性并且已经分配了一定的空间,才能在这里被成功释放掉。

    经查,变量 $mlat 既具有可分配属性,并且已经分配了一定的空间,但是为什么还是无法正常被释放掉呢?

    原来出错的原因是对 $mlat 变量的索引引用超出了它的范围:

    (1) allocate(mlat(LenMLAT)) 分配的索引默认从1开始,也即 $mlat 的有效索引范围为 [1, LenMLAT];

    (2)deallocate(mlat) 也默认从1开始释放,这样也需要引用 $mlat 在 [1, LenMLAT] 之间的值。

    可是,程序中仅仅对 mlat(0:LenMLAT-1) 的部分作了初始化,而 mlat(LenMLAT) 的位置并没有初始化,也就无法释放掉。

    感兴趣的同学可以测试下第10-12句的注释部分,看它是否也一样报错。

    也正因为 Fortran 关于数组可自定义索引范围的特点,在初始化、引用和释放数组变量时需要特别检查索引的起止范围,保证全文一致,以免出现难以查找原因的“吐核”错误。

    核吃多了,容易噎着……

  • 相关阅读:
    AI人脸识别SDK接入 — 参数优化篇(虹软)
    虹软人脸识别ArcFace2.0 Android SDK使用教程
    虹软免费人脸识别SDK注册指南
    python3+arcface2.0 离线人脸识别 demo
    Android利用RecyclerView实现列表倒计时效果
    将博客搬至CSDN
    Retrofit动态设置支持JSON和XML格式转换工厂
    Android 简单统计文本文件字符数、单词数、行数Demo
    [雨]个人项目设计分析
    Android:随机生成算数四则运算简单demo(随机生成2~4组数字,进行加减乘除运算)
  • 原文地址:https://www.cnblogs.com/snake553/p/7822994.html
Copyright © 2011-2022 走看看