我在ODE求解器套件中实现事件检测。以下是我正在调试的实现中的一段代码,并注意到一个奇怪的行为。一旦根查找例程成功返回根,则执行第一个if块(ROOTFINDING_ERR == 0) - 第1到14行 - 这是预期的行为。但是,一旦块完成执行,执行意外跳转到对应于(ROOTFINDING_ERR == 0) - 第20行的ELSE块的最后一个语句,并且语句EVENT_OUT(j)= .FALSE。在第21行执行ENDIF之前执行。
1 IF (ROOTFINDING_ERR == 0) THEN
2 IF ((ABS(EVENT_TIMES(1, j) - T_STAR) > &
3 NEARBY_ROOTS_ABSTOL) &
4 .AND. (EVENT_ITER < EVENT_ITER_MAX)) THEN
5 EVENT_TIMES(1, j) = T_STAR
6 EVENT_TIMES(2, j) = DBLE(j)
7 EVENT_TEST(j) = .TRUE.
8 EVENT_OUT(j) = .TRUE.
9 ELSE
10 EVENT_TIMES(1, j) = T_STAR
11 EVENT_TIMES(2, j) = DBLE(j)
12 EVENT_TEST(j) = .FALSE.
13 EVENT_OUT(j) = .TRUE.
14 ENDIF
15 ELSE
16 EVENT_TIMES(1, j) = T_STAR
17 EVENT_TIMES(2, j) = DBLE(j)
18 ! Dont test this event further
19 EVENT_TEST(j) = .FALSE.
20 EVENT_OUT(j) = .FALSE.
21 ENDIF
我认为这与一些内存访问/分配问题有关,并在可执行文件上运行DrMemory(Valgrind之类的工具)。 DrMemory确实指出一些读取是未初始化的,我将进一步研究。
我想知道从哪里开始。我使用gdb逐步完成了代码,并且难以隔离DrMemory抱怨的“未初始化的读取”。我打开-Wall, -Wextra, -fbounds-check
等来确定编译器是否能够捕获它。我也尝试用x32dbg反汇编exe,但是由于x32dbg不支持DWARF符号,因此不会读取调试符号。
答案 0 :(得分:1)
从显示的代码中我看不出任何错误的原因。因此我猜测错误是由我们看不到的东西引起的。
现在,接下来的内容并没有解决这个难题,而是试图绕过它......
...显示的代码可以简化为
EVENT_TIMES(1, j) = T_STAR
EVENT_TIMES(2, j) = DBLE(j)
IF (ROOTFINDING_ERR == 0) THEN
EVENT_OUT(j) = .TRUE.
IF ((ABS(EVENT_TIMES(1, j) - T_STAR) > &
NEARBY_ROOTS_ABSTOL) &
.AND. (EVENT_ITER < EVENT_ITER_MAX)) THEN
EVENT_TEST(j) = .TRUE.
ELSE
EVENT_TEST(j) = .FALSE.
ENDIF
ELSE
! Dont test this event further
EVENT_TEST(j) = .FALSE.
EVENT_OUT(j) = .FALSE.
ENDIF
......甚至更进一步......
EVENT_TIMES(1, j) = T_STAR
EVENT_TIMES(2, j) = DBLE(j)
EVENT_OUT(j) = ROOTFINDING_ERR == 0
EVENT_TEST(j) = ((ROOTFINDING_ERR == 0) .AND. &
(ABS(EVENT_TIMES(1, j) - T_STAR) > &
NEARBY_ROOTS_ABSTOL) &
.AND. (EVENT_ITER < EVENT_ITER_MAX))