Array dengan ukuran tetap harus diukur sejak program ditulis, padahal banyak data baru diketahui ukurannya saat program berjalan. Atribut allocatable menerapkan teknik alokasi tunda, yakni penentuan ukuran array ditunda hingga pernyataan allocate dijalankan. Topik ini membahas deklarasi dan alokasi array allocatable, pemeriksaan status dengan allocated, dealokasi otomatis saat lingkup berakhir, serta alokasi ulang otomatis yang diperkenalkan standar Fortran 2003.
Deklarasi dan allocate#
Deklarasi allocatable menandai array dengan tanda titik dua pada setiap dimensinya, misalnya real, allocatable :: data(:) untuk array satu dimensi. Ukurannya tidak muncul pada deklarasi karena memang belum ditentukan. Pernyataan allocate(data(3)) kemudian menyediakan memori untuk tiga elemen sekaligus menetapkan bentuk array tersebut. Sebelum dialokasi, akses atas array ini merupakan error, sehingga status alokasinya perlu diperiksa terlebih dahulu.
Kegagalan alokasi, misalnya karena memori tidak cukup, dapat ditangani dengan argumen stat. Pernyataan allocate(data(3), stat=status_alokasi) menempatkan nol pada status_alokasi apabila berhasil dan nilai positif apabila gagal, sehingga program dapat memeriksa dan merespons kegagalannya sendiri. Tanpa stat, kegagalan alokasi menghentikan program dengan pesan error. Bentuk dengan stat dipilih apabila alokasi berpotensi gagal dan program masih perlu menjalankan langkah penutup, misalnya menyimpan hasil yang sudah diperoleh.
Pemeriksaan allocated dan dealokasi#
Fungsi intrinsik allocated menerima satu array allocatable dan mengembalikan true apabila array itu sedang dialokasi. Pemeriksaan ini wajib dilakukan sebelum deallocate, karena mendekalokasi array yang belum dialokasi merupakan error. Program pada bagian ini menerapkan aturan tersebut melalui pola if (allocated(data)) deallocate(data) sebelum mengalokasi ulang data.
Program berikut merangkum perilaku alokasi tunda dari deklarasi sampai akhir lingkup, sehingga setiap pernyataan yang dibahas pada bagian ini memiliki keluaran yang menyertainya. Array data dan skor menampung nilai contoh yang sederhana, sedangkan subrutin periksa_lingkup memperlihatkan dealokasi otomatis ketika lingkup prosedurnya berakhir. Jalankan berkasnya untuk mengamati urutan keluarannya.
program demo_allocatable
implicit none
real, allocatable :: data(:)
integer, allocatable :: skor(:)
integer :: status_alokasi
print *, "allocated sebelum allocate =", allocated(data)
allocate(data(3), stat=status_alokasi)
print *, "status allocate =", status_alokasi
data = [1.5, 2.5, 3.5]
print *, "data =", data
skor = [80, 90, 75, 100] ! alokasi otomatis pada assignment
print *, "skor =", skor
skor = [85, 95] ! realokasi otomatis, bentuk baru
print *, "skor =", skor, " ukuran =", size(skor)
if (allocated(data)) deallocate(data)
allocate(data(4), source=0.0) ! alokasi sekaligus pengisian
print *, "data dengan source=0.0 =", data
call periksa_lingkup()
contains
subroutine periksa_lingkup()
real, allocatable :: sementara(:)
allocate(sementara(2))
sementara = [9.0, 8.0]
print *, "sementara di dalam subrutin =", sementara
! dealokasi otomatis berlangsung saat subrutin berakhir
end subroutine periksa_lingkup
end program demo_allocatable# kompilasi program contoh
gfortran demo-allocatable.f90 -o demo-allocatable
# jalankan program
./demo-allocatable allocated sebelum allocate = F
status allocate = 0
data = 1.50000000 2.50000000 3.50000000
skor = 80 90 75 100
skor = 85 95 ukuran = 2
data dengan source=0.0 = 0.00000000 0.00000000 0.00000000 0.00000000
sementara di dalam subrutin = 9.00000000 8.00000000Baris pertama keluaran memperlihatkan F dari allocated sebelum alokasi, dan status allocate bernilai nol menandakan alokasi berhasil. Array sementara di dalam subrutin periksa_lingkup didealokasi otomatis saat subrutin berakhir, tanpa pernyataan deallocate apa pun. Perilaku ini mencegah kebocoran memori (memory leak), yakni memori yang tidak digunakan lagi tetapi tidak pernah dilepaskan.
Alokasi otomatis pada assignment#
Sejak Fortran 2003, assignment ke array allocatable mengatur alokasinya sendiri, sehingga pemberian nilai lewat tanda sama dengan tidak memerlukan alokasi manual terlebih dahulu. Bila array di sisi kiri belum dialokasi, array itu dialokasi mengikuti bentuk sisi kanan, dan bila bentuknya berbeda, array tersebut dialokasi ulang. Pada program di atas, skor = [80, 90, 75, 100] mengalokasikan skor otomatis menjadi empat elemen, lalu skor = [85, 95] mengubah ukurannya menjadi dua elemen tanpa satu pernyataan allocate pun.
Alternatif kedua adalah argumen source= pada allocate, yang menyediakan memori dan mengisi nilainya dalam satu pernyataan. Pemanggilan allocate(data(4), source=0.0) menghasilkan empat elemen bernilai nol, sehingga tidak ada elemen yang berisi nilai sisa memori. Bentuk ini berguna saat setiap elemen perlu nilai awal yang sama sebelum perhitungan dimulai.
Kapan allocatable digunakan#
Atribut allocatable dipilih bila ukuran data baru diketahui saat program berjalan, misalnya banyaknya rekaman yang dibaca dari berkas, banyaknya titik data hasil masukan, atau hasil antara yang ukurannya ditentukan perhitungan sebelumnya. Array dengan ukuran tetap tetap dipilih bila ukurannya memang konstan, misalnya vektor tiga komponen, karena deklarasinya lebih sederhana dan langkah alokasinya tidak diperlukan. Dengan kata lain, pilihan antara keduanya mengikuti pertanyaan apakah ukuran data merupakan bagian dari masalah atau bagian dari program.
Atribut ini juga berlaku pada komponen tipe turunan (derived type), yakni tipe data buatan pengguna yang mengelompokkan beberapa nilai di dalam satu nama, sehingga setiap objek tipe tersebut dapat membawa array yang panjangnya berbeda-beda.
! tidak-dijalankan
type :: catatan_suhu
character(len=8) :: sensor
real, allocatable :: pengukuran(:) ! banyaknya data baru diketahui saat berjalan
end typeDalam Fortran modern, kebutuhan array dinamis dipenuhi dengan allocatable, sedangkan pointer disisakan untuk kasus yang benar-benar memerlukan nama alternatif atas data yang sudah ada. Pembatasan ini mengurangi risiko kesalahan manajemen memori yang menjadi konsekuensi kebebasan pointer, seperti memori yang tidak pernah dilepaskan.
Atribut ini juga berguna pada argumen prosedur. Argumen dummy yang dideklarasikan real, intent(in) :: x(:) menerima array dengan bentuk apa pun melalui mekanisme bentuk diasumsikan (assumed shape), sedangkan argumen dummy yang dideklarasikan allocatable dapat dialokasi di dalam prosedur dan hasilnya terbawa kembali kepada pemanggil. Fungsi juga boleh mengembalikan array allocatable, sehingga ukuran hasil ditentukan saat fungsi berjalan, misalnya array hasil penyaringan yang banyaknya elemen baru diketahui setelah penyaringan dilakukan.
Ringkasan#
allocatablemenunda penentuan ukuran array hinggaallocate, dan argumenstatmelaporkan keberhasilan alokasi tanpa menghentikan program.allocatedmemeriksa status alokasi, dan array allocatable lokal didealokasi otomatis saat lingkupnya berakhir.- Assignment ke array allocatable sejak Fortran 2003 mengalokasikan atau mengalokasikan ulang array itu mengikuti bentuk sisi kanan.
- Alokasi ulang yang berulang di dalam perulangan menimbulkan biaya kinerja yang tidak terlihat pada kode.
Referensi#
- GNU Fortran compiler manual — GNU Project — Dokumentasi resmi gfortran, termasuk referensi intrinsik ALLOCATED dan status dukungan standar Fortran 2003.
- Learn — fortran-lang.org — Kumpulan tutorial resmi komunitas Fortran yang memuat praktik terbaik penggunaan array allocatable.