#fortran #heap-memory #lapack #heap-corruption
#fortran #куча-память #lapack #повреждение кучи
Вопрос:
Я столкнулся с проблемой повреждения кучи в Visual Studio 2008 с компилятором Intel Fortran 11. Я работаю над 64-разрядной версией Windows 7.
Это вызов подпрограммы (F77) lapack в моей программе F90:
call dgetrs('N', nbParams, one, a, nbParams, ipv, x, nbParams, err)
Перед этим вызовом отладчик показывает ожидаемые значения для всех параметров. a и x обозначают две «распределяемые» переменные с размером (nbParams, nbParams) и (nbParams) соответственно.
Однако после выполнения этой строки выполнение останавливается из-за нарушения доступа к местоположению чтения 0x0000000000000001. Поскольку я скомпилировал lapack в режиме отладки, я могу войти в вызов, и я вижу, что все, кроме ‘TRANS’, повреждается только в первом операторе DGETRS .
SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
...
CHARACTER TRANS
INTEGER INFO, LDA, LDB, N, NRHS
...
INTEGER IPIV( * )
DOUBLE PRECISION A( LDA, * ), B( LDB, * )
......
INFO = 0 **--> Now all input vars but TRANS are corrupted or dereferenced!**
Я перепробовал все, и я не могу найти проблему. Кто-нибудь может помочь мне найти проблему?
Спасибо за вашу помощь!
Комментарии:
1. каковы типы фактических аргументов
dgetrs
? Lapack недостаточно бережно относится к несоответствиям типов параметров2. можете ли вы добавить объявление переменных, которые у вас есть в вызывающем, и как вы выполняете выделение?
3. целое число nbParams, единица, ошибка; двойная точность, размерность (:), указатель :: x; двойная точность, размерность (:,:), выделяемый :: x; выделить (x(nbParams), stat=err); целое число, размерность (:), выделяемый :: ipv; ЗатемЯ выделяю память для массивов: выделить(a(nbParams, nbParams), stat= err); выделить (ipv(nbParams), stat= err);
4. Был ли предыдущий вызов DGETRF успешным?
5. Не могли бы вы опубликовать минимальный компилируемый пример, демонстрирующий проблему?
Ответ №1:
Такого рода проблемы обычно возникают при использовании массивов предполагаемой формы без интерфейса. Попробуйте объявить интерфейс, такой как:
INTERFACE
SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
CHARACTER TRANS
INTEGER INFO, LDA, LDB, N, NRHS
INTEGER IPIV( * )
DOUBLE PRECISION A( LDA, * ), B( LDB, * )
END SUBROUTINE
END INTERFACE