Fortran仅用ALLOCATABLE变量实现链表可行性及指针优势对比
Fortran 可分配变量实现链表相关问题解答
仅用ALLOCATABLE变量不使用指针能否在Fortran中构建链表?
是可以实现基础链式结构的。Fortran标准允许派生类型包含同类型的可分配成员,你设计的Allocation_List节点类型、Allocation_LinkedList链表类型的结构本身符合语法要求,能正常通过编译。
你提出的实现方案能否正常运行?有哪些问题和缺陷?
简单场景下的基础增删操作可以正常运行,但存在非常多限制和缺陷:
- 所有权唯一导致操作灵活性极差:
ALLOCATABLE变量的内存所有权是独占的,你没办法在不转移所有权、不做深拷贝的前提下用第二个变量引用同一个节点。遍历链表的时候要么转移节点所有权破坏原链表结构,要么拷贝节点产生极高的额外开销 - 节点操作复杂度高,易出问题:插入、删除中间节点时,你需要手动做多次所有权转移:先把原后继节点的所有权转存到临时变量,再分配新节点,再把临时变量的所有权转移给新节点的
Next成员。整个流程比指针操作繁琐很多,非常容易出现内存泄漏或者节点被意外释放的问题 - 无法实现复杂链表结构:双向链表、循环链表、带公共子链的链表这类需要同一节点被多个位置引用的结构,用纯
ALLOCATABLE完全无法实现,毕竟一个节点不可能同时属于两个所有者 - 空节点判断容易混淆:你只能用
.not. allocated()来模拟空节点,没办法区分「逻辑上没有后继节点」和「节点分配失败/意外释放」两种状态,排查问题难度大 - 性能损耗大:所有非连续的节点访问都要伴随所有权转移或者数据拷贝,和指针直接访问内存的效率差距非常大
Fortran中指针相比ALLOCATABLE变量的优势有哪些?
- 支持多别名引用:多个指针可以指向同一个内存地址,不管是链表遍历、双向/循环链表实现,都不需要转移所有权也不需要拷贝数据,完美适配链式结构的需求
- 操作逻辑简单:插入、删除节点只需要修改指针的指向即可,不需要处理复杂的所有权转移逻辑,代码更简洁,出错概率更低
- 空状态标识清晰:指针有专门的
null()初始值,可以用associated()函数明确判断指针的关联状态,和内存分配失败的状态可以完全区分开,逻辑判断和调试都更方便 - 适用场景更广:指针除了可以自主分配内存,还可以指向已经存在的
ALLOCATABLE变量、局部变量甚至数组切片,不需要额外拷贝就能共享数据,能实现很多ALLOCATABLE做不到的功能
内容的提问来源于stack exchange,提问作者Akhil Akkapelli
相关产品推荐
相关产品推荐

