Fortran构建指向数组的指针数组时函数返回相同地址问题
问题根源分析
你提供的代码中makeArray始终返回相同内存地址的核心原因:函数内定义的a是局部自动可分配数组,函数执行结束退出作用域时,a会被编译器自动释放,此时返回的指针属于野指针,指向的内存区域已经被标记为可复用,后续再次调用makeArray时,会重复使用这块刚被释放的内存,因此返回的指针地址完全相同,修改任意指针指向的内容都会影响其他所有指针。这种野指针行为属于Fortran标准中的未定义行为,随时可能出现数据损坏、程序崩溃等问题,必须修正。
你需要实现的是第二维长度不一的锯齿数组(Ragged Array),以下是两种安全的实现方案:
方案1:可分配数组封装(推荐,无野指针风险)
不需要额外构造函数,直接在自定义类型中使用可分配数组成员,按需分配第二维即可:
module mymodule implicit none type :: IntArray integer, allocatable :: arr(:) integer :: id end type IntArray end module mymodule program test use mymodule implicit none type(IntArray), allocatable :: ptrarray(:) integer :: i ! 预分配指针槽位,和你的需求一致 allocate(ptrarray(5)) ! 生成结果时按需分配不同长度的第二维数组,放入对应槽位 allocate(ptrarray(1)%arr(1277), source=0) ptrarray(1)%id = 1 allocate(ptrarray(2)%arr(13567), source=0) ptrarray(2)%id = 2 ptrarray(1)%arr(12) = 10 ! 验证两个数组地址不同 do i=1, 2 write(*,*) ptrarray(i)%id write(*,*) LOC(ptrarray(i)%arr) end do end program
方案2:修正原有指针实现
如果一定要保留指针构造函数的写法,需要确保返回的指针指向的内存不会在函数退出时被自动释放,直接将堆上分配的内存赋值给返回指针即可:
module mymodule contains function makeArray(size) result(res) integer, intent(in) :: size integer, pointer :: res allocate(res(size), source=0) end function makeArray end module mymodule program test use mymodule implicit none type :: IntPointer integer, pointer :: ptr(:) integer :: id end type type(IntPointer), allocatable :: ptrarray(:) integer :: i allocate(ptrarray(5)) ptrarray(1)%ptr => makeArray(1277) ptrarray(1)%id = 1 ptrarray(2)%ptr => makeArray(13567) ptrarray(2)%id = 2 ptrarray(1)%ptr(12) = 10 do i=1, 2 write(*,*) ptrarray(i)%id write(*,*) LOC(ptrarray(i)%ptr) end do end program
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

