• Aucun résultat trouvé

ALLOCATE Statement

Dans le document The Fortran 2003 Handbook (Page 194-200)

6 Using Data

16. FOR_2003(K:L)%PARTS(I:J) ! ILLEGAL

6.7 Pointers and Allocatable Variables

6.7.1 ALLOCATE Statement

The ALLOCATE statement creates space for variables with the ALLOCATABLE or POINTER attribute. If the variable is a pointer, it becomes associated with the newly created space.

The form of the ALLOCATE statement (R623) is:

ALLOCATE ( [ type-specifier :: ] allocation-list [ , allocate-option-list ] ) Type specifiers are described in 4. They may specify intrinsic or derived types.

An allocation (R628) is:

allocate-object [ ( allocate-shape-specification-list ) ] An allocate object (R629) is one of:

variable-name structure-component

Disassociated Undefined

Associated

25 50 100

Undefined association status Defined association status, undefined target

Defined association status, defined target Defined association status,

disassociated

Figure 6-1 States of a pointer

POINTER P(:) ALLOCATE (P(3))

NULLIFY (P)

ALLOCATE (P, SOURCE = [25,50,100]) Associated

Using Data 189

and an allocate shape specification (R630) is:

[ allocate-lower-bound : ] allocate-upper-bound An allocate-option (R624) is one of:

STAT = scalar-integer-variable

ERRMSG = scalar-default-character-variable SOURCE = source-expr

Rules and restrictions:

1. The allocate lower bound and allocate upper bound must be scalar integer expres-sions.

2. Each allocate object must be a data pointer or an allocatable variable.

3. An allocate-shape-specification-list may appear if and only if the allocate object is an array. The number of allocate shape specifications must agree with the declared rank of the array.

4. If an allocate object in a statement has a deferred type parameter, a type specifier or a SOURCE option must appear in the statement.

5. If a type specifier appears, it must specify a type that is compatible with each allo-cate object (5.2).

6. Either a type specifier or a SOURCE option must appear if any allocate object in a statement is unlimited polymorphic or is of abstract type (4.4.12.3).

7. A type parameter value in a type specifier must be an asterisk if and only if each allocate object is a dummy argument for which the corresponding type parameter is assumed.

8. If a type specifier appears, the kind type parameter values of each allocate object must be the same as the corresponding kind type parameters in the type specifier;

length type parameter values may differ.

9. If the SOURCE option appears, type-specifier must not appear, and the allocation list must contain only one allocate object, which must be type compatible (5.2) with source-expr.

10. The rank of source-expr must be either zero or the same as that of the single allo-cate object. Corresponding kind type parameters must have the same values.

11. Neither the STAT variable, source-expr, nor the ERRMSG variable may be allocated in the ALLOCATE statement in which they appear; nor may they depend on the value, bounds, length type parameters, allocation status, or association status of any allocate object in the same statement.

190 Chapter 6 12. An allocate object or a bound or type parameter must not depend on the value of the STAT variable, the value of the ERRMSG variable, or on the value, bounds, length type parameters, allocation status, or association status of any allocate ob-ject in the same ALLOCATE statement.

If a type-specifier or a source-expr appears, it determines the dynamic type and type parameters of the allocate object(s). If neither appears, allocation of a polymorphic ob-ject creates an obob-ject with a dynamic type and type parameters that are the same as its declared type.

If source-expr appears, it must be conformable with the allocate object. If the allo-cation is successful, the value of the allocate object becomes that of source-expr.

If a STAT variable appears, it is set to zero if the allocation is successful and is set to a processor dependent positive value if there is an error condition. Each allocate ob-ject that was successfully allocated will have an allocation status of allocated or a pointer association status of associated; each allocate object that was not successfully allocated will retain its previous allocation status or pointer association status. If there is no STAT variable, the program terminates when an error condition occurs.

An error condition occurs if:

1. there is insufficient memory for the requested allocations or some other anomaly is detected by the processor,

2. an allocate object in an ALLOCATE statement has an allocation status of allocated, 3. the value specified for a type parameter in a type specification differs from a corre-sponding nondeferred value specified in the declaration of any of the allocate ob-jects, or

4. the value of a type parameter in source-expr is different from the value of a nonde-ferred length type parameter of the allocate object.

If the ERRMSG option appears and an error condition occurs during execution of an ALLOCATE statement, the processor will assign an explanatory message to the errmsg character variable. Otherwise, the processor will not change the value of the errmsg variable.

An example of an allocate statement is:

ALLOCATE (pressure (i), mat (-1 : total, 0:50), STAT = alloc_err) When an ALLOCATE statement is executed for an array, the values of the lower and upper bound expressions determine the shape of the array. If an entity in one of these expressions is subsequently redefined, the shape of the allocated array is not changed. If the lower bound is omitted, the default is 1. If the upper bound is less than the lower bound, the extent in that dimension is 0 and the array has zero size, in which case no memory is allocated for the array.

An allocate object may be of type character. If it has a character length of zero, no memory is allocated.

Using Data 191 An example of an ALLOCATE statement in which the value and dynamic type are determined by reference to another object is:

CLASS (*), ALLOCATABLE :: ANY CLASS (*), POINTER :: PICK . . .

PICK => . . .

ALLOCATE (ANY, SOURCE = PICK) ! Allocate ANY with the value and ! dynamic type of PICK

An example of an (unnecessary) ALLOCATE statement with a type specifier is:

TYPE BOOK

CHARACTER (LEN = : ), ALLOCATABLE :: TITLE END TYPE BOOK

TYPE (BOOK) :: BOOKLIST (100) CHARACTER (LEN = 1000) :: HOLDER DO I = 1, 100

READ *, HOLDER ! Get title

J = LEN_TRIM (HOLDER) ! Get length of title IF (J <= 1) EXIT

ALLOCATE (CHARACTER (LEN = J) :: BOOKLIST(I) % TITLE) BOOKLIST(I) % TITLE = HOLDER(1:J)

END DO

The ALLOCATE statement can be omitted because allocation is accomplished as a part of the assignment in the statement following the ALLOCATE statement.

6.7.1.1 Allocation of Allocatable Variables

An allocatable variable has an allocation status of allocated or unallocated at any time during the execution of a program. Unlike pointers, there is no undefined allocation status. At the beginning of execution of a program, an allocatable variable has a status of unallocated. Its status changes to allocated if it appears in a successfully executed ALLOCATE statement, if it is allocated during assignment (7.5.2), or if it is given that status by the allocation transfer intrinsic MOVE_ALLOC (13.3.3.1). An allocatable vari-able with this status may be referenced, defined, or deallocated. The intrinsic function ALLOCATED (13.3.1.4) returns true for such a variable.

The status of an allocatable variable becomes unallocated if it is successfully deal-located (6.7.3.1) or if it is given that status by the allocation transfer intrinsic. An allo-catable variable with this status must not be referenced, defined, or supplied as an actual argument corresponding to a nonallocatable dummy argument, except to certain intrinsic inquiry functions. The intrinsic function ALLOCATED returns false for such a variable.

When the allocation status of an allocatable variable changes, the allocation status of any associated allocatable variable changes accordingly. Allocation of an allocatable

192 Chapter 6 variable establishes values for the deferred type parameters of all associated allocatable variables.

An example of using the intrinsic function ALLOCATED to query the allocation status of an allocatable variable is:

REAL, ALLOCATABLE :: X(:,:,:) . . .

IF(.NOT. ALLOCATED(X)) ALLOCATE (X(-6:2,10,3))

The array X cannot be referenced until it has been allocated and assigned a value; it can be used as an argument to the ASSOCIATED intrinsic, as that is not a reference (2.4). X must be declared with a deferred-shape array specification and the ALLOCATABLE at-tribute.

An unsaved allocatable object that is a local variable of a procedure has a status of unallocated at the beginning of each invocation of the procedure. The status may change during execution of the procedure. An unsaved allocatable object that is a local variable of a module has an initial status of unallocated. The status may change during execution of the program. When an object of derived type is created by an ALLOCATE statement without a SOURCE option, any allocatable ultimate components have an al-location status of unallocated.

In the following example, allocation occurs when an array constructor is assigned to the allocatable array GAMEBOARD. In the first ALLOCATE statement, the value and dynamic type and properties of STORE are determined by reference to GAME-BOARD. In the second ALLOCATE statement, they are determined by reference to CELLS.

TYPE POSITION

INTEGER :: COLOR, PIECE LOGICAL :: FILLED = .FALSE.

END TYPE POSITION

TYPE (POSITION), ALLOCATABLE :: GAMEBOARD (:,:) CLASS (*), ALLOCATABLE :: TEMP_STORE (:,:) REAL, POINTER :: CELLS (:,:)

. . . READ *, SIZE

GAMEBOARD = RESHAPE ( &

[ ( ( [ POSITION (COLOR = I, PIECE = J), &

I = 1, SIZE), J = 1, SIZE) ] , &

SHAPE = [SIZE, SIZE] ) . . .

ALLOCATE (TEMP_STORE, SOURCE = GAMEBOARD) . . .

CELLS => . . .

IF (.NOT.ALLOCATED(TEMP_STORE)) ALLOCATE (TEMP_STORE, SOURCE = CELLS)

Using Data 193

6.7.1.2 Allocation of Pointers

When an object with the POINTER attribute is allocated, space is created, and the pointer is associated with that space, which becomes the pointer target. Such an allo-cated pointer target implicitly has the target attribute which allows additional pointers to point to that target or part of that target. Additional pointers may become associated with the same target by pointer assignment (7.5.5.1). A pointer target may be a variable with the ALLOCATABLE attribute if the variable also has the TARGET attribute.

It is not an error to allocate a pointer that is already associated with a target. In this case, a new pointer target is created as required by the attributes of the pointer and any array bounds, type, and type parameters specified by the ALLOCATE statement.

The previous association of the pointer is lost. If there was no other way to access the previous target, it becomes inaccessible. This is sometimes referred to as a “memory leak”.

The ASSOCIATED intrinsic function may be used to query the association status of a pointer only if the association status of the pointer is defined. There is no means to determine whether a pointer with defined association status was associated by an ALLOCATE statement; the ALLOCATED intrinsic function cannot have a pointer argument. The ASSOCIATED function also may be used to inquire whether a pointer is associated with a particular target or whether two pointers are associated with the same target.

At the beginning of execution of a function with a pointer result, the association status of the result pointer is undefined. Before such a function returns, it must associ-ate a target with this pointer or cause the association status of the pointer to become disassociated.

Pointers can be used in many ways; an important usage is the creation of linked lists. For example:

TYPE NODE

INTEGER :: VALUE

TYPE (NODE), POINTER :: NEXT => NULL( ) END TYPE NODE

TYPE(NODE), POINTER :: LIST . . .

ALLOCATE (LIST) LIST % VALUE = 17 ALLOCATE (LIST % NEXT)

The first two executable statements create a node pointed to by LIST and put the value 17 in the VALUE component of the node. The next statement creates a second node pointed to by the NEXT component of the first node. The NEXT component of the sec-ond node is disassociated because of default initialization specified for the derived type NODE. Its VALUE component is undefined.

194 Chapter 6

Dans le document The Fortran 2003 Handbook (Page 194-200)