Dynamic memory allocation is a crucial concept in Fortran, especially when dealing with data structures whose size cannot be determined at compile time. This topic will cover the basics of dynamic memory allocation, including how to allocate and deallocate memory, and practical examples to illustrate these concepts.

Key Concepts

  1. Dynamic Memory Allocation:

    • Allows the program to request memory during runtime.
    • Useful for handling data structures with sizes that are not known until the program is running.
  2. ALLOCATE Statement:

    • Used to allocate memory for variables.
    • Syntax: ALLOCATE(variable_name(size))
  3. DEALLOCATE Statement:

    • Used to free the allocated memory.
    • Syntax: DEALLOCATE(variable_name)
  4. Automatic Arrays:

    • Arrays whose size is determined at runtime but are automatically deallocated when they go out of scope.

Practical Examples

Example 1: Allocating and Deallocating a Simple Array

PROGRAM DynamicArrayExample
  IMPLICIT NONE
  INTEGER, ALLOCATABLE :: array(:)
  INTEGER :: n, i

  ! Ask the user for the size of the array
  PRINT *, 'Enter the size of the array:'
  READ *, n

  ! Allocate memory for the array
  ALLOCATE(array(n))

  ! Initialize the array
  DO i = 1, n
    array(i) = i * 2
  END DO

  ! Print the array
  PRINT *, 'Array elements:'
  DO i = 1, n
    PRINT *, array(i)
  END DO

  ! Deallocate the memory
  DEALLOCATE(array)
END PROGRAM DynamicArrayExample

Explanation:

  • The program prompts the user to enter the size of the array.
  • The ALLOCATE statement is used to allocate memory for the array based on the user input.
  • The array is initialized and printed.
  • Finally, the DEALLOCATE statement is used to free the allocated memory.

Example 2: Using Automatic Arrays

PROGRAM AutomaticArrayExample
  IMPLICIT NONE
  CALL ProcessArray(5)
END PROGRAM AutomaticArrayExample

SUBROUTINE ProcessArray(n)
  IMPLICIT NONE
  INTEGER, INTENT(IN) :: n
  INTEGER :: i
  REAL :: array(n)

  ! Initialize the array
  DO i = 1, n
    array(i) = i * 1.5
  END DO

  ! Print the array
  PRINT *, 'Array elements:'
  DO i = 1, n
    PRINT *, array(i)
  END DO
END SUBROUTINE ProcessArray

Explanation:

  • The subroutine ProcessArray takes an integer n as an argument.
  • An automatic array array is declared with size n.
  • The array is initialized and printed.
  • The array is automatically deallocated when the subroutine exits.

Exercises

Exercise 1: Dynamic Matrix Allocation

Task: Write a program that dynamically allocates a 2D matrix based on user input, initializes it with random numbers, prints the matrix, and then deallocates the memory.

Solution:

PROGRAM DynamicMatrixExample
  IMPLICIT NONE
  REAL, ALLOCATABLE :: matrix(:,:)
  INTEGER :: rows, cols, i, j

  ! Ask the user for the size of the matrix
  PRINT *, 'Enter the number of rows:'
  READ *, rows
  PRINT *, 'Enter the number of columns:'
  READ *, cols

  ! Allocate memory for the matrix
  ALLOCATE(matrix(rows, cols))

  ! Initialize the matrix with random numbers
  CALL RANDOM_SEED()
  DO i = 1, rows
    DO j = 1, cols
      CALL RANDOM_NUMBER(matrix(i, j))
    END DO
  END DO

  ! Print the matrix
  PRINT *, 'Matrix elements:'
  DO i = 1, rows
    PRINT *, (matrix(i, j), j = 1, cols)
  END DO

  ! Deallocate the memory
  DEALLOCATE(matrix)
END PROGRAM DynamicMatrixExample

Exercise 2: Dynamic Array of Structures

Task: Create a program that dynamically allocates an array of structures to store student information (name and grade), initializes the array, prints the information, and deallocates the memory.

Solution:

PROGRAM DynamicStructArrayExample
  IMPLICIT NONE
  TYPE :: Student
    CHARACTER(LEN=50) :: name
    REAL :: grade
  END TYPE Student

  TYPE(Student), ALLOCATABLE :: students(:)
  INTEGER :: n, i

  ! Ask the user for the number of students
  PRINT *, 'Enter the number of students:'
  READ *, n

  ! Allocate memory for the array of students
  ALLOCATE(students(n))

  ! Initialize the array
  DO i = 1, n
    PRINT *, 'Enter name for student ', i, ':'
    READ *, students(i)%name
    PRINT *, 'Enter grade for student ', i, ':'
    READ *, students(i)%grade
  END DO

  ! Print the student information
  PRINT *, 'Student Information:'
  DO i = 1, n
    PRINT *, 'Name: ', students(i)%name, ', Grade: ', students(i)%grade
  END DO

  ! Deallocate the memory
  DEALLOCATE(students)
END PROGRAM DynamicStructArrayExample

Common Mistakes and Tips

  • Forgetting to Deallocate Memory: Always ensure that you deallocate memory to avoid memory leaks.
  • Incorrect Allocation Size: Double-check the size of the allocation to ensure it matches the intended dimensions.
  • Using Uninitialized Memory: Always initialize allocated memory before using it to avoid undefined behavior.

Conclusion

Dynamic memory allocation in Fortran allows for flexible and efficient use of memory, especially when dealing with data structures whose size is not known at compile time. By mastering the ALLOCATE and DEALLOCATE statements, you can create more dynamic and adaptable programs. Practice with the provided examples and exercises to solidify your understanding of these concepts.

© Copyright 2024. All rights reserved