Fortran Coder

查看: 20558|回复: 15
打印 上一主题 下一主题

[混编] deallocate内存访问错误及DLL问题

[复制链接]

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
跳转到指定楼层
楼主
发表于 2015-4-16 02:43:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 andy8496 于 2015-4-16 02:47 编辑

又遇到看不见摸不着的问题了!
运行到一个deallocate时,出现图中的错误了。被deallocate的real数组中的数值正常。
可能是什么原因?
这是一个比较大的程序,最近在做一些修改。可以肯定的是,相同位置以前老代码是没有遇到这个问题的。

另一个问题:
当A(main.exe)项目引用B项目(test.dll)时,只要设置A依赖B,不需要在A中添加B相关的文件,就能直接编译通过。但是debug运行时会提示找不着test.dll。
我目前是生成后,将B中的test.dll复制到A的debug文件夹中。还有别的办法吗?

1.jpg (19.82 KB, 下载次数: 547)

1.jpg

2.jpg (15.04 KB, 下载次数: 596)

2.jpg
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2015-4-16 08:51:53 | 只看该作者
有另外的问题,一般提倡另外发帖。(已帮你分隔)

问题1,不容易解决,通常这种错误都需要详细debug解决。有时候还可能需要反汇编解决。

问题2,一般我是设置 B 项目的输出路径,直接输出到 A 项目所在的位置。

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

板凳
发表于 2015-4-16 18:42:16 | 只看该作者
本帖最后由 pasuka 于 2015-4-16 18:43 编辑

在deallocate语句前面加个判断
if(allocated(**))deallocate(**)
还有可能是Fortran和C/C++混编的时候,数组越界,所以deallocate的时候出问题

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
地板
 楼主| 发表于 2015-4-16 19:35:37 | 只看该作者
pasuka 发表于 2015-4-16 18:42
在deallocate语句前面加个判断
if(allocated(**))deallocate(**)
还有可能是Fortran和C/C++混编的时候,数 ...

应该不是这个原因。我使用deallocate的时候,加了最后的状态参数。还是谢谢了。

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
5#
 楼主| 发表于 2015-4-16 19:43:41 | 只看该作者
我想我找到为什么出错的原因了。
我在a.exe中使用了b.dll的一个子程序。这个子程序的输出参数有一个是allocatable数组。
我在a.exe中声明了一个allocatable的数组,这个数组经b.dll中的子程序运算、输出,至此一切正常。
但是,用完这个allocatable的数组后,我在a.exe调用deallocate释放它时,就出现一楼所示的问题了。
怎么破?

附件中的工程是我做的例子,能再现这个问题。恳请大侠出手!在此谢过!

test.rar

6.07 KB, 下载次数: 7

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

6#
发表于 2015-4-16 19:46:46 | 只看该作者
良好的编程习惯:
谁打开,谁关闭。谁分配,谁释放。

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
7#
 楼主| 发表于 2015-4-16 22:07:51 | 只看该作者
如果一定要这么做,有解决办法吗?

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

8#
发表于 2015-4-16 22:13:39 | 只看该作者
1. 在 test_main 里声明可分配数组
2. 调用 test_dll 里的一个函数,获得数组的大小 n
3. 在 test_main 里完成分配。allocate( x(n) )
4. 把 x 传递给 test_dll 里完成计算
5. 在 test_main 里 deallocate

由于可分配数组的内部实现,是编译器的问题(而语法是不干涉具体实现的)。而 DLL 又是windows的事情。
这几者间比较难以协调。

实际上,就算不用 DLL,单纯的 Fortran 工程,我也建议谁定义,谁分配,谁释放。

如果你确实确实要在主程序定义,DLL里分配,主程序释放。那我可能帮不了你。

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

9#
发表于 2015-4-16 22:31:35 | 只看该作者
用gfortran编译成dll再调用没发现问题
只是在调用前加了个检查
  if(allocated(iv_int))deallocate(iv_int)
  call allocate_test(iv_int)

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
10#
 楼主| 发表于 2015-4-16 23:52:02 | 只看该作者
真是太奇怪了!
1.上面的代码Debug的时候报错,但是Release的时候就运行正常!!!
2.正常情况下,allocate过的数组是不能再allocate的。但是,test_main.f90这样写居然没有报错:
program main
use test_dll
implicit none
  integer,allocatable :: iv_int(:)
  integer :: iStatus,i
  do i=1,10
    call allocate_test(iv_int,i)
    write(*,*) iv_int
  enddo
  stop
end program
这意思是说:dll中的allocate不关主程序的事?
3.但是这么写又有问题了:
program main
use test_dll
implicit none
  integer,allocatable :: iv_int(:)
  integer :: iStatus,i
  do i=1,10
    call allocate_test(iv_int,i)
    write(*,*) iv_int
  enddo
  allocate(iv_int(8)) ! 到这里报错了,说这是分配过的数组
  stop
end program

4.难道确实是分配了,只是只有dll知道分配到哪儿了,主程序不知道?于是又这么改了下:
Dll加上这么一个函数:
subroutine deallocate_test(iv)
!DEC$ ATTRIBUTES STDCALL,REFERENCE,DLLEXPORT,ALIAS:"deallocate_test"::deallocate_test
implicit none
  integer,allocatable :: iv(:)
  integer :: iStatus
  deallocate(iv,stat=iStatus)
return
end subroutine

主程序这么写:
program main
use test_dll
implicit none
  integer,allocatable :: iv_int(:)
  integer :: iStatus,i
  do i=1,10
    call allocate_test(iv_int,i)
    write(*,*) iv_int
  enddo
  call deallocate_test(iv_int)
  allocate(iv_int(8))
  deallocate(iv_int,stat=iStatus)
  stop
end program

这么就一切正常了。
5.那回到1,Release的时候主程序又是如何知道dll分配的地址,成功的deallocate掉的呢?


哎,真是一团浆糊啊!有没有完美的解决之道啊?

您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-25 00:27

Powered by Tencent X3.4

© 2013-2024 Tencent

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