Niedawno odkryliśmy, że wykonywaliśmy przypisanie do nieprzydzielonej tablicy w Fortranie. Kompilator GNU gfortran nie złapał błędu, a kod działa zarówno pod OS X jak i Linux. Jednak te same błędy segmentacji kodu na komputerze IBM Power PC.Automatyczne przydzielanie macierzy przy przydzielaniu w Fortranie
Moje pytanie brzmi, czy poniższy kod jest prawidłowy? Wygląda na to, że tablica przypisana do array
automatycznie przydziela pamięć na niektórych architekturach, ale nie na inne. Czy istnieją tu konkretne szczegóły dotyczące wdrożenia?
Kod jest mieszany C/kod Fortran:
#include <stdlib.h>
void assign_array_(double x[], int* n);
void print_array_();
int main()
{
int n,i;
double *x;
n = 5;
x = (double*) malloc(sizeof(double)*n);
for (i = 0; i < n; i++)
x[i] = (double) i;
assign_array_(x,&n);
print_array_();
return 0;
}
I kod Fortran:
MODULE test_mod
DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:) :: array
integer :: nsize
END MODULE test_mod
SUBROUTINE assign_array(x,n)
USE test_mod
IMPLICIT NONE
INTEGER :: n
DOUBLE PRECISION :: x(n)
CALL test_allocated()
array = x
CALL test_allocated()
nsize = n
END SUBROUTINE assign_array
SUBROUTINE print_array()
USE test_mod, ONLY: nsize, array
IMPLICIT NONE
INTEGER :: i
DO i = 1,nsize
WRITE(6,'(F24.16)') array(i)
END DO
END SUBROUTINE print_array
SUBROUTINE test_allocated()
USE test_mod
IMPLICIT NONE
IF (ALLOCATED(array)) THEN
WRITE(6,*) 'Array is allocated'
WRITE(6,*) 'size is ', SIZE(array)
ELSE
WRITE(6,*) 'Array is NOT allocated'
END IF
END SUBROUTINE test_allocated
wyjściowych (jeśli działa) wynosi:
Array is NOT allocated
Array is allocated
size is 5
0.0000000000000000
1.0000000000000000
2.0000000000000000
3.0000000000000000
4.0000000000000000
I tutaj jest wyjście na Power PC:
Array is NOT allocated
Segmentation fault (core dumped)
Podsumowując: Działa po skompilowaniu pod GNU (GNU Fortran (MacPorts gcc5 5.4.0_0) 5.4.0) gfortran na OSX (arch: x86_64h) i Linux (w wirtualnej maszynie hostowanej na OSX, GNU Fortran (Ubuntu 4.9.4-2ubuntu1 ~ 14.04.1) 4.9.4), ale nie uruchamia się po skompilowaniu na Power PC (arch: ppc64) skompilowanym przy użyciu GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) . W naszym oryginalnym kodzie implementacja Power PC uległa dopiero późniejszej segregacji w kodzie, do którego odwołano się do wpisów z przypisaną tablicą, co sprawia, że nasz "bug" (jeśli w rzeczywistości jest to błąd) jest naprawdę trudny do wyśledzenia.
Jakie jest prawidłowe zachowanie powyższego kodu?
Nie sprawdzasz, czy malloc się powiódł. – stark
Właśnie dodałem czek, a malloc odnosi sukcesy we wszystkich przypadkach. – Donna
Jeśli tablica nie została przydzielona, 'tablica = x' jest nielegalna. – stark