作者sin55688 (单手挑藏獒)
看板Fortran
标题[问题] 主程式 call subroutine 会爆掉的原因
时间Mon Nov 23 18:08:13 2015
编译後错误讯息:
forrtl: severe (157): Program Exception - access violation
除错的结果,我认为跟记忆体使用限制有关,但不清楚原因,想请教板上的前辈
下面是我碰到的情形,我用简单的语法表示
=======================================
程式1 可执行成功
=======================================
real(8) :: A(512,512,512)
A = 1d0
call sub(512,512,512,A)
A = A+A
=======================================
程式2 执行失败
=======================================
real(8) :: A(512,512,512)
A = 1d0
call sub(511,511,511,A(1:511,1:511,1:511)
A = A+A <-------在这步会出现错误讯息
=======================================
subroutine sub(n1,n2,n3,A)
implict none
integer,intent(in) :: n1,n2,n3
real(8),intent(in) :: A(n1,n2,n3)
end subroutine
副程式本身并无任何作用
所以认为是呼叫副程式时,传入资料导致主程式记忆体空间出现问题
但不了解传入整个阵列A 与 部分阵列A(1:511,1:511,1:511)
因为我的理解,subroutine 是传送记忆体位置,并非传送值
为何後者会导致错误发生,希望有经验的前辈可以指教,谢谢
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.113.22.208
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Fortran/M.1448273296.A.D92.html
1F:→ noonee: 我不知道为何compile 出错 但是就算成功两个也是不一样的 11/23 23:23
2F:→ noonee: 啊 懂了 主程式里宣告了A的大小传给sub 11/23 23:24
3F:→ noonee: 但是sub里又重新宣告了他的大小 而且大小不一样 11/23 23:25
4F:→ noonee: 所以你要传递部份是可以的 但是需要另外写一个叫B 11/23 23:25
5F:→ noonee: B的大小要跟sub里宣告的一样 11/23 23:26
6F:→ noonee: 如果你是不想写死array的大小 那就要用allocatable 11/23 23:26
7F:→ noonee: 但是用allocatable的话 就只能用module传递 11/23 23:26
8F:→ noonee: 事实上这就是为何你去看一堆老程式 老是宣告一个很大的 11/23 23:27
9F:→ noonee: array 然後主副程式都用共一个parameter来宣告大小 11/23 23:28
主程式中 A 阵列其实是用 allocate 配置空间的
而 sub 的 A 阵列应该只是告知传入阵列的大小,不具备配置记忆体功能
不知我的理解是否错误?
在我测试例子当中,A阵列非常的大,如果缩小成 256^3 则不会有问题
所以我在猜想是不是 A(1:511,1:511,1:511)传入副程式时
这种部分阵列会而外再吃记忆体,导致记忆体不足?
※ 编辑: sin55688 (140.113.125.200), 11/24/2015 01:16:17
10F:→ rex0707: 我设A(11,11,11)这样的矩阵大小 两种方法都可以执行 11/24 01:26
11F:→ rex0707: 如果设成512 会显示记忆体不足 所以应该是记忆体不足所造 11/24 01:26
12F:→ rex0707: 成的问题 11/24 01:26
13F:→ blc: sub里的A阵列记忆体位置应该跟主程式的一样,所以就…… 11/24 17:16
14F:推 hiyiyi: 副程式的矩阵宣告用A(:,:,:),自动设定维度大小 11/26 21:01
15F:→ crazy10167: 8*512**3使用记忆体约1G,程式2的方法副程式又再吃1G, 12/12 22:41
16F:→ crazy10167: 你系统如果是32位元就会不够 12/12 22:41