【发布时间】:2013-03-28 12:06:09
【问题描述】:
我在退出程序时遇到了这个未处理的异常:
Unhandled exception at 0x102fe274 (msvcr100d.dll) in Parameters.exe: 0xC0000005: Access violation reading location 0x00000005.
调试器在此行的名为 crtdll.c 的模块中停止:
onexitbegin_new = (_PVFV *) DecodePointer(__onexitbegin);
调用堆栈的第一行写着:
msvcr100d.dll!__clean_type_info_names_internal(__type_info_node * p_type_info_root_node=0x04a6506c) 第 359 行 + 0x3 字节 C++
程序会一直保留在内存中,直到我关闭 IDE。
我更习惯于使用托管语言进行开发,所以我认为我的代码维护有问题。代码本身读取内存映射文件并将其与指针关联:
SUBROUTINE READ_MMF ()
USE IFWIN
USE, INTRINSIC :: iso_c_binding
USE, INTRINSIC :: iso_fortran_env
INTEGER(HANDLE) file_mapping_handle
INTEGER(LPVOID) memory_location
TYPE(C_PTR) memory_location_cptr
INTEGER memory_size
INTEGER (HANDLE) file_map
CHARACTER(5) :: map_name
TYPE(C_PTR) :: cdata
integer :: n = 3
integer(4), POINTER :: A, C
real(8), POINTER :: B
TYPE STRUCT
integer(4) :: A
real(8) :: B
integer(4) :: C
END TYPE STRUCT
TYPE(STRUCT), pointer :: STRUCT_PTR
memory_size = 100000
map_name = 'myMMF'
file_map = CreateFileMapping(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ memory_size,
+ map_name // C_NULL_CHAR )
memory_location = MapViewOfFile(file_map,
+IOR(FILE_MAP_WRITE, FILE_MAP_READ),
+ 0, 0, 0 )
cdata = TRANSFER(memory_location, memory_location_cptr)
call c_f_pointer(cdata, STRUCT_PTR, [n])
A => STRUCT_PTR%A
B => STRUCT_PTR%B
C => STRUCT_PTR%C
RETURN
END
当我用完 c 指针后,我应该释放它们吗?我调查了一下,但看不到我在 Fortran 中是如何做到的......
感谢您的帮助!
【问题讨论】:
-
释放内存会更干净,但是当程序退出时操作系统会为你做这件事。 Fortran 无法释放在 C 中分配的内存……您将为此使用 C 例程。此外,
integer(4)和real(8)可能是也可能不是 4 和 8 字节数。它们是种类 4 和种类 8,它们依赖于处理器(编译器)。见stackoverflow.com/questions/3170239/… 和stackoverflow.com/questions/10520819/what-does-real8-mean -
P.S.由于您使用的是
iso_fortran_env,因此您可以使用一种可靠且便携的方式来请求特定的尺寸编号。对于 4 字节整数:integer (int32);对于 8 字节实数:real (real64)。至少如果您的编译器具有 ISO Fortran 环境的 Fortran 2008 版本。 -
M.S.B,感谢您对字节大小的评论。我使用英特尔编译器,但我不知道我可以使用 (int32) 等来控制数据类型的字节大小。我将继续使用它。
标签: pointers memory-management fortran unhandled-exception fortran-iso-c-binding