【问题标题】:FORTRAN-Invalid write of size 4FORTRAN - 大小为 4 的无效写入
【发布时间】:2014-01-13 10:45:16
【问题描述】:

我使用 MPI 编写了 Fortran 代码,因为我是 valgrind 的新手,所以我无法找到问题所在。运行检查时出现此错误:

==3040== Invalid write of size 4
==3040==    at 0x804BFE0: MAIN__ (NS.f90:174)
==3040==    by 0x804E190: main (NS.f90:321)
==3040==  Address 0x5746f20 is 0 bytes after a block of size 8 alloc'd
==3040==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3040==    by 0x804C5F3: MAIN__ (NS.f90:198)
==3040==    by 0x804E190: main (NS.f90:321)
==3040== 
==3041== Invalid write of size 4
==3041==    at 0x804BFE0: MAIN__ (NS.f90:174)
==3040== Invalid write of size 4
==3040==    at 0x804C036: MAIN__ (NS.f90:175)
==3040==    by 0x804E190: main (NS.f90:321)
==3041==    by 0x804E190: main (NS.f90:321)
==3041==  Address 0x5748bbc is 0 bytes after a block of size 12 alloc'd
==3041==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3040==  Address 0x5746f58 is 0 bytes after a block of size 8 alloc'd
==3040==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3040==    by 0x804C729: MAIN__ (NS.f90:198)
==3040==    by 0x804E190: main (NS.f90:321)
==3040== 
==3041==    by 0x804C5F3: MAIN__ (NS.f90:198)
==3041==    by 0x804E190: main (NS.f90:321)
==3041== 
==3040== Invalid write of size 4
==3040==    at 0x804C087: MAIN__ (NS.f90:176)
==3040==    by 0x804E190: main (NS.f90:321)
==3040==  Address 0x5746f90 is 0 bytes after a block of size 8 alloc'd
==3040==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3040==    by 0x804C862: MAIN__ (NS.f90:198)
==3040==    by 0x804E190: main (NS.f90:321)
==3040== 
==3041== Invalid write of size 4
==3041==    at 0x804C036: MAIN__ (NS.f90:175)
==3041==    by 0x804E190: main (NS.f90:321)
==3041==  Address 0x5748bfc is 0 bytes after a block of size 12 alloc'd
==3041==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3041==    by 0x804C729: MAIN__ (NS.f90:198)
==3041==    by 0x804E190: main (NS.f90:321)
==3041== 
==3040== Invalid write of size 4
==3040==    at 0x804C1C5: MAIN__ (NS.f90:178)
==3040==    by 0x804E190: main (NS.f90:321)
==3040==  Address 0x5746fc8 is 0 bytes after a block of size 8 alloc'd
==3040==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3040==    by 0x804C99B: MAIN__ (NS.f90:198)
==3040==    by 0x804E190: main (NS.f90:321)
==3040== 
==3041== Invalid write of size 4
==3041==    at 0x804C087: MAIN__ (NS.f90:176)
==3041==    by 0x804E190: main (NS.f90:321)
==3041==  Address 0x5748c3c is 0 bytes after a block of size 12 alloc'd
==3041==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3041==    by 0x804C862: MAIN__ (NS.f90:198)
==3041==    by 0x804E190: main (NS.f90:321)
==3041== 
==3040== 
==3041== Invalid write of size 4
==3041==    at 0x804C1C5: MAIN__ (NS.f90:178)
==3041==    by 0x804E190: main (NS.f90:321)
==3041==  Address 0x5748c7c is 0 bytes after a block of size 12 alloc'd
==3041==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)

第 174 到 178 行包含这段代码:

A(I) = -0.5 * (0.5 * (1.0 + EPX) * CX(I-1, J) + DX)
B(I) = (1 + DX + 0.5 * EPX * CX(I, J))
C(I) = 0.5 * (0.5 * (1 - EPX) * CX(I+1, J) - DX)
R(I) = 0.5 * (0.5 * (1 + EPY) * CY(I, J-1) + DY) * OMEGA(I, J-1) + (1 - DY - 0.5 * EPY * CY(I, J)) * OMEGA(I, J) + 0.5 * (-0.5 * (1 - EPY) * CY(I, J+1) + DY) * OMEGA(I, J+1)

谁能告诉我这里出了什么问题?我还收到其他错误,例如:

==3041== Invalid read of size 4
==3041==    at 0x804C271: MAIN__ (NS.f90:183)
==3041==    by 0x804E190: main (NS.f90:321)
==3041==  Address 0x5748c40 is 4 bytes after a block of size 12 alloc'd
==3041==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)

第 183 行指的是:

R(N) = R(N) - C(N) * OMEGA(N+1, J)

如果有人能告诉我问题出在哪里,我将不胜感激。

这里是代码块:

A = 0.0
B = 0.0
C = 0.0
R = 0.0
X = 0.0
DO J = 1, M
DO I = 1, N 
IF (U(I, J) > 0.0) THEN
EPX = 1.0
ELSE 
EPX = -1.0
ENDIF
IF (V(I, J) > 0.0) THEN
EPY = 1.0
ELSE 
EPY = -1.0
ENDIF
A(I) = -0.5 * (0.5 * (1.0 + EPX) * CX(I-1, J) + DX)
B(I) = (1 + DX + 0.5 * EPX * CX(I, J))
C(I) = 0.5 * (0.5 * (1 - EPX) * CX(I+1, J) - DX)
R(I) = 0.5 * (0.5 * (1 + EPY) * CY(I, J-1) + DY) * OMEGA(I, J-1) + (1 - DY - 0.5 * EPY * CY(I, J)) * OMEGA(I, J) + 0.5 * (-0.5 * (1 - EPY) * CY(I, J+1) + DY) * OMEGA(I, J+1)
ENDDO
R(1) = R(1) - A(1) * OMEGA(0, J)
R(N) = R(N) - C(N) * OMEGA(N+1, J)
ENDDO

【问题讨论】:

  • A、B、C、R 是如何声明/分配的?

标签: fortran mpi valgrind


【解决方案1】:

您很可能遇到索引错误并溢出数组边界。这是一个常见错误,编译器可以协助调试。对于 gfortran,请使用 -fcheck=all,对于英特尔,请使用 -check all。其他编译器也有类似的能力。

之后,您必须确保您的数组具有正确的维度,并且您正在使用正确的上限和下限运行循环。

在这种情况下,我们无法说出错误在哪里,因为您没有显示变量的声明。

【讨论】:

  • 感谢你们,我可以解决问题。这是由于在外循环末尾错误分配向量!
猜你喜欢
  • 2016-07-23
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
相关资源
最近更新 更多