找回密码
 注册
Simdroid-非首页
查看: 619|回复: 13

[3. Fortran] 【求助】Fortran数组几个疑问!

[复制链接]
发表于 2003-11-14 17:25:45 | 显示全部楼层 |阅读模式 来自 湖北襄阳
今天在程序的调试中发现了几个现象,想和大家探讨一下。
fortran 为 cvf6.6
一、
定义两数组: A(5340),B(5340,50)
调试时如下语句通不过。
read(1,*)(A(I),B(I, : ),I=1,5340)
提示:(NTDLL.DLL) : 0xC0000005: Access Violation.
改为如下语句就可以通过。
do I=1,5430
read(1,*)A(I),B(I,: )
end do
是不是因为数组太大的缘故?(程序里面还很多组这样大的数组)。
二、
subroutine F1()
real *8, pointer, dimension( : ) :: A
给A数组分配空间
.....
end  
subroutine F2(A)
real *8, pointer, dimension( : ) :: A
对数组A操作
......
end
对于如上的两个子函数,如果A数组定义比较大时,调试通不过。
提示: 0xC000008C: Array Bounds Exceeded.
在debug中发现在函数F2中A没有分配空间。也就是F1中的A没有传给F2。
并非A数组超过的边界。
如果A数组定义比较小的话就没有这个问题。是不是也是因为A数组太大而无法在子函数间传递?如果真是这样的话,该如何解决呢?
请版主及各位高手指点!
谢谢!
发表于 2003-11-14 23:24:00 | 显示全部楼层 来自 美国

回复: 【求助】Fortran数组几个疑问!

Simdroid开发平台
对于一,我试了没有问题,建议打一下6.6B的补丁试试。
对于二,我觉得F1, F2应该改成如下形式更好:
  
SUBROUTINE F1()
!
REAL (8), ALLOCATABLE :: A(
!
ALLOCATE(A(50))
CALL F2(A, 50)
...
!
END SUBROUTINE F1
  
SUBROUTINE F2(A, N)
!
REAL (8) :: A(N)
...
!
END SUBROUTINE F2

评分

1

查看全部评分

发表于 2003-11-15 09:22:50 | 显示全部楼层 来自 北京

回复: 【求助】Fortran数组几个疑问!

yexm wrote:
今天在程序的调试中发现了几个现象,想和大家探讨一下。
fortran 为 cvf6.6
一、
定义两数组: A(5340),B(5340,50)
调试时如下语句通不过。
read(1,*)(A(I),B(I, : ),I=1,5340)
提示:(NTDLL.DLL) : 0xC0000005: Access Violation.
改为如下语句就可以通过。
do I=1,5430
read(1,*)A(I),B(I,: )
end do
是不是因为数组太大的缘故?(程序里面还很多组这样大的数组)。
二、
subroutine F1()
real *8, pointer, dimension( : ) :: A
给A数组分配空间
.....
end  
subroutine F2(A)
real *8, pointer, dimension( : ) :: A
对数组A操作
......
end
对于如上的两个子函数,如果A数组定义比较大时,调试通不过。
提示: 0xC000008C: Array Bounds Exceeded.
在debug中发现在函数F2中A没有分配空间。也就是F1中的A没有传给F2。
并非A数组超过的边界。
如果A数组定义比较小的话就没有这个问题。是不是也是因为A数组太大而无法在子函数间传递?如果真是这样的话,该如何解决呢?
请版主及各位高手指点!
谢谢!

  
第一个问题:第一个问题,READ语句的第一种写法,要求被读的量一次性提供,第二种写法读了5000多次,这是区别
 楼主| 发表于 2003-11-15 10:06:41 | 显示全部楼层 来自 湖北武汉

回复: 回复: 【求助】Fortran数组几个疑问!

freepu wrote:
对于一,我试了没有问题,建议打一下6.6B的补丁试试。
对于二,我觉得F1, F2应该改成如下形式更好:
  
SUBROUTINE F1()
!
REAL (8), ALLOCATABLE :: A(
!
ALLOCATE(A(50))
CALL F2(A, 50)
...
!
END SUBROUTINE F1
  
SUBROUTINE F2(A, N)
!
REAL (8) :: A(N)
...
!
END SUBROUTINE F2

  
谢谢freepu老兄。
对于第二个问题,按照你的方法修改之后果然可以通过了。确实有效。
但是不知道为什么我原来的方法就不行了?
把指针作为子例子程序的变元来传递应该没问题的呀。
我百思不得其解。还请freepu老兄解释一下好吗?
 楼主| 发表于 2003-11-15 10:09:18 | 显示全部楼层 来自 湖北武汉

回复: 回复: 【求助】Fortran数组几个疑问!

galever wrote:
第一个问题:第一个问题,READ语句的第一种写法,要求被读的量一次性提供,第二种写法读了5000多次,这是区别

  
但是问题是我把所有的数据都放在一个文件里。
无论一次性杜如,还是多次读入都可以保证数据的完整性。
为什么第一种方法就通不过?而第二种方法就可以了呢?
 楼主| 发表于 2003-11-16 10:23:24 | 显示全部楼层 来自 湖北武汉

回复: 回复: 回复: 【求助】Fortran数组几个疑问!

yexm wrote:
[quote]galever wrote:
第一个问题:第一个问题,READ语句的第一种写法,要求被读的量一次性提供,第二种写法读了5000多次,这是区别

  
但是问题是我把所有的数据都放在一个文件里。
无论一次性杜如,还是多次读入都可以保证数据的完整性。
为什么第一种方法就通不过?而第二种方法就可以了呢? [/quote]
  
我把我的程序和输入文件上传了,请高手能指点!
在用F5调试的时第一个文件的输入没有问题,而第二个就出现问题了。
我就想是不是因为第二个文件太大了的缘故?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2003-11-16 11:34:42 | 显示全部楼层 来自 美国

回复: 【求助】Fortran数组几个疑问!

这段程序完全跟堆栈大小有关,CVF的缺省堆栈是1MB,你可以在你的连接选项中增加如下/stack:7000000(自己定个足够大的),程序运行成功!我想这跟隐式循环占用堆栈有关吧(不是十分清楚)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

1

查看全部评分

 楼主| 发表于 2003-11-16 15:24:29 | 显示全部楼层 来自 湖北武汉

回复: 【求助】Fortran数组几个疑问!

非常感谢热心的freepu大侠。
我想应该是堆栈的问题吧。
因为第二种方法是一次性读入数据。如果数据量太大的话确实是有导致堆栈溢出的可能。
发表于 2003-11-17 16:46:46 | 显示全部楼层 来自 陕西西安

回复: 【求助】Fortran数组几个疑问!

还是FREEPU水平高,我就没有想到。
发表于 2003-11-17 22:41:48 | 显示全部楼层 来自 美国

回复: 【求助】Fortran数组几个疑问!

客气了,大家互相学习。我也是对这个有点兴趣,查了些资料才发现这个问题。yexm的例子很有意思,没有他的例子也是难以发现的,同时也从他的例子中学到了指针的运用,很好,多谢yexm!管理员给分也很大方呀,多谢了!
 楼主| 发表于 2003-11-17 22:52:35 | 显示全部楼层 来自 湖北武汉

回复: 回复: 【求助】Fortran数组几个疑问!

freepu wrote:
客气了,大家互相学习。我也是对这个有点兴趣,查了些资料才发现这个问题。yexm的例子很有意思,没有他的例子也是难以发现的,同时也从他的例子中学到了指针的运用,很好,多谢yexm!管理员给分也很大方呀,多谢了!

  
freepu太谦虚了!
不过对于我最初提出的第二个问题,关于数据量大时指针做变元出错的问题,我还是不得其解。
我开始也想是不是也是因为数据太大的缘故造成的。
我在编译时按照freepu的方法加大了堆栈空间,但是遗憾的是还是不行?
按照freepu的方法是可以通过的,没问题。
但是我觉得我最初的方法从理论上来说是没有问题的,而且在数据小的时候也是通过了的。
不知道那位高手能指点一下。
谢谢了。
 楼主| 发表于 2003-11-23 10:47:58 | 显示全部楼层 来自 湖北武汉

回复: 【求助】Fortran数组几个疑问!

经过这段时间的查阅资料。我现在终于明白了我第二个问题的原因了。现在把我的理解在这儿谈谈,希望和大家一起探讨。
原来我第二个问题的方法是错误的。并非是因为数组大小的缘故。
我对程序作了修改,自己当时没有注意,误以为是数组大小的缘故。
这里有两个概念我要强调一下:
1。在fortran中变元的传递是按照地址来传递的,这是关键的所在。与C不同的是在C中是按照值来传递的。
2。在fortran中指针与C和C++的指针的概念是不一样的。指针变量并没有真正取得并存放着所指向的对象的内存地址,因此就不能对指针变量进行内存地址方式的操作,而只能通过变量名访问。
  
所以如果按照如下方法的话:
subroutine F1()  
real *8, pointer, dimension( : ) :: A  
给A数组分配空间  
call F2(A)
.....  
end  
subroutine F2(A)  
real *8, pointer, dimension( : ) :: A  
对数组A操作  
......  
end  
  
在F2子程序中就正确的传递数组。其实在F1子程序中已经给指针A分配好了内存空间。这时候的指针A其实就相当于一个数组名。所以在调用F2程序时,就应该按照数组作为变元的方法来调用就可以了。
  
subroutine F1()  
real *8, pointer, dimension( : ) :: A  
allocate( A(NT) )
call F2(A,NT)
.....  
end  
subroutine F2(A,NT)  
integer :: NT
real *8, dimension( NT ) :: A  
对数组A操作  
......  
end  
  
这样调用就一点问题也没有了。

评分

1

查看全部评分

发表于 2003-11-23 11:05:44 | 显示全部楼层 来自 美国

回复: 【求助】Fortran数组几个疑问!

这样说,用指针和用动态数组并没有什么区别了,是么?
如果这样指针的优势是什么?
 楼主| 发表于 2003-11-24 09:29:11 | 显示全部楼层 来自 湖北武汉

回复: 【求助】Fortran数组几个疑问!

根据我的理解指针和动态数组的基本功能一样,都可以根据需要来动态的分配内存地址。
但是,指针比动态数组要灵活的多。指针可以随时的改变所指向的对象。也就是说一个指针不同的时候所代表的变量是不同的。而动态数组织能改变自身的内存大小。我想这就是指针的优势所在吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-5-3 17:53 , Processed in 0.076939 second(s), 19 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表