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

返回Fortran类指针的构造函数被重复调用的原因排查

为何返回类指针的Fortran构造函数被调用两次并触发SIGBUS错误?

你的代码在gfortran 11下运行正常,但在14.2.0(Apple M1环境)中出现foo_construct被调用两次、触发SIGBUS内存访问错误的问题,根源在于多态指针函数的写法不符合Fortran标准,新版本编译器的标准合规性处理暴露了这个问题。

问题代码

模块代码:

module test

implicit none

type :: foo
end type

contains

function make()
implicit none

class (foo), pointer :: make

make => foo_construct()

end function

function foo_construct()
implicit none

class (foo), pointer :: foo_construct

allocate(foo_construct)
write (*,*) 'construct_foo'

end function

end module

驱动程序:

program test_construct
use test
implicit none

class (foo), pointer :: foo_instant

foo_instant => make()
deallocate(foo_instant)

end program

运行异常输出

% ./test_prog              
 construct_foo
 construct_foo

Program received signal SIGBUS: Access to an undefined portion of a memory object.

Backtrace for this error:
#0  0x102b5eccf
#1  0x102b5dd23
#2  0x18cd7a583
#3  0x102523cff
#4  0x102523d57
zsh: bus error  ./test_prog

原因分析

在Fortran标准中,返回多态指针的函数不能直接通过make => foo_construct()这种方式赋值。新版本gfortran对标准的执行更严格,会额外生成一次foo_construct调用以处理多态指针的返回语义,导致两次内存分配:

  • 第一次调用foo_construct分配的内存被make引用,最终传递给foo_instant;
  • 第二次调用分配的内存没有被任何变量持有,成为野指针,同时编译器处理多态指针返回时的错误操作触发了SIGBUS错误。

修复方案

修改make函数,通过临时指针接收返回值后再赋值给函数返回指针:

function make()
implicit none
class (foo), pointer :: make
class (foo), pointer :: temp_ptr

temp_ptr => foo_construct()
make => temp_ptr
end function

或者直接在make函数内完成对象分配,避免嵌套的指针返回函数:

function make()
implicit none
class (foo), pointer :: make

allocate(make)
write(*,*) 'construct_foo'
end function

修改后,foo_construct只会被调用一次,内存错误也会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:57:16