Pointers 
Variable Declarations
•	Declarations served dual purpose
–	Specification of range of values and operations
–	Specification of Storage requirement

•	All programs required FIXED amount of memory
–	number of variables fixed by the declaration 
–	decided by their types

•	One exception:  Allocatable array
–	Size of the array depends upon input
Static and Dynamic Allocation
•	Compiler uses the declaration to allocate memory for a program
•	Static allocation (or fixed  memory requirements) leads you to be conservative
•	Wastage of space and poor performance for some inputs
•	Analogy:  Two-way traffic in City roads
•	Better management: allocate on demand
–	Initially allocate minimal
–	Allocate more when needed
–	Deallocate when not needed
–	Dynamic Memory management
Dynamic Memory allocation
•	Memory allocation not fixed 
•	nor done at compile-time
•	It is done at run-time
•	at run-time no declarations - only executable instructions
•	need special instructions for allocation - executable declarations so to say
•	Allocate and Deallocate constructs for dynamic arrays
•	we need more general mechanism for arbitrary organization of data
Pointers
•	One problem with dynamic allocation:
•	How do we access the newly allocated memory locations
•	How did we access the statically allocated memory?
•	Access the new locations by their addresses
•	This is against the principle of high level languages:
–	abstract memory locations and machine details
–	disallow direct control over resources – unsafe
•	is there any other way?
•	pointer variables is a compromise
•	Pointer variable contains addresses rather than data values
•	Addresses point to the newly allocated memory locations and hence called pointers
Pointer variables
•	They store addresses that identify locations where actual data values reside
•	Pointer variables declared statically so compiler can allocate memory
•	Static declaration of pointer variables! That is funny
–	we do not know a priori our memory requirement and hence our quest for dynamic memory locations
•	Static declarations can allocate only a fixed number of pointers
•	How do we create and access unbounded number of locations
•	Answer: Dynamic creation of pointers themselves (more on this later)
Pointer variable Declarations
•	Declarations specify types - set of data values and operations
•	What types pointers are or should be?
•	Pointer variables store addresses
•	Addresses are numerical values - non negative integers
•	Are they non negative integers? No, quite a different kind
•	Pointers always contain same type of values whatever they point to
–	Can point to integers, reals, characters, arrays or structures
•	Are all pointers of the same type
Pointers are of different types
•	Only way of accessing dynamic objects is through pointers
•	What is pointed to is distinguished - real, integer, character, array etc.
•	Essential to distinguish the pointers for the same reason
•	So Pointers are of different types:
–	integer pointer, real pointer, array pointer, etc
•	Pointer types are decided by the types of those pointed to
•	Declarations specify these
Pointer Declarations
•	Examples:
		integer, pointer:: p1, p2
		real, pointer:: r1, r2

		integer, dimension(:), pointer:: array_ptr
		real, dimension(:,:), pointer:: matrix_ptr
•	These declarations allocate memory for the pointer variables
•	Pointer variables have addresses like normal addresses
•	But they store addresses - the addresses will be assigned dynamically (during execution)
•	Addresses assigned should correspond to locations where data values with the specified type is stored 
•	Special statements are provided for this purpose
Target variables
•	Simplest pointer assignment:
–	store the address of a location allocated for a variable
•	Example:
		p1 => x
		r1 => z
		matrix_ptr => m
	where
–		p1,r1, matrix_ptr as before
–		x,z,m are integer, real and matrix variables
•	The types should match
•	rhs variables resolved to addresses!
–	contrast with conventional assignment
Pointer assignment

Target declarations
•	For a variable to act as target explicit declaration required:

		integer, target :: x
		real, target :: z
		integer, dimension(10,10), target :: matrix_ptr
Targets can be pointers
•	Suppose p1 and p2 are of pointers of the same type

•	Further suppose p2 points to a location of appropriate type

•	Then
		p1 => p2

•	makes p1 point to whatever p2 points to

Before Assignment

After assignment

Dereferencing of pointers
•	Two meanings for pointers in
		p1 => p2
•	p2 has an address and contains another address
•	What is assigned to p1 is the content of p2
•	p2 on the rhs refers to the contents of p2 rather than p2 itself
•	This is called Dereferencing
•	Contrast this when target is ordinary variable
		p1 => x
–	what is assigned here is not the content of x but the address of x
Another example
•	Consider
	
write *, p1, p2

•	What is printed?
•	The address associated with p1,p2?
•	No, the values stored at those addresses
•	The pointers are dereferenced to get the values
Pointers in Normal Assignment
•	Pointers can appear in normal assignments:
•	     p1 = p2
•	     p1 = p2 + p3

•	Suppose, p1, p2 and p3 points to targets x, y and z
•	The above is equivalent to
•	      x = y
•	      x = y + z

•	Note that p1 is also dereferenced here
Rules for dereferencing
=>
•	The lhs should be evaluated to an address (or pointer)
•	The rhs should also evaluate to an address
=
•	The lhs should evaluate to an address
•	The rhs should evaluate to a value
print *, x
–	x should be a value
•	So the rule is:
		Dereference the pointer as much required to 	evaluate to appropriate value
Use of Pointers
•	Suppose you wish to exchange two arrays arr1, arr2 of Dimension(100,100)
•	Solution 1:
		temp = arr1
		arr1 = arr2
		arr2 = temp
•	involves exchange of 10,000 values!
•	Solution 2:
		Real, Dimension(:,:), pointer:: p1,p2,temp
		p1 => arr1
		p2 => arr2
		temp => p1
		p1 => p2
		p2 => temp
•	Exchange of just two pointers
Dynamic Allocation of Memory
•	So far, pointers point to already existing variables
•	The amount of used memory is still static
•	For dynamic memory requirement, additional mechanism needed
•	Allocate and Deallocate instructions
•	Allocate ‘creates’ required memory and decllocate ‘destroys’ memory
Allocate Command
•	Simplest allocate statement
			Allocate(p, stat = s)
•	This allocates appropriate memory space,
•	address pointed to by the pointer p
•	s returns an integer value which indicates whether allocation successful or not
		s = 0 means success, 
                    failure otherwise
•	Stat = is optional but should always be used
•	If allocation fails and if no stat = clause, then the program will abort
Some examples
		integer, pointer:: p1
		integer, dimension(:):: p2
		...
		allocate(p1, Stat=p1_stat)
		allocate(p2(1:10), Stat = p2_stat)
		'''"

		p1 = x + y
		p2(2) = p2(1) + p1

•	Note the dimension specification in p2 declaration
Deallocate Command
•	Memory created using Allocate command can be destroyed when not needed
–	Deallocate(p, Stat = p_stat)
•	Deallocates the memory, if p_stat = 0
•	What does p point to after this command?
•	It points to null value
•	Pointer assignment or allocation associates the pointer with some address
•	Deallocation breaks this association
•	Referring to pointer that is disassociated is an error
–	The program will abort
Checking Association
•	To avoid aborting, association status of pointer should be checkable
•	Intrinsic function Associated  used for this purpose
associated(p)
•	returns the value .TRUE. iff p is associated with a target
•	A more general form is
			associated(p, tvar)
•	returns .TRUE iff p is associated with the target tvar
•	Association with a pointer can be removed using
			nullify(p)
•	which disassociates p with any target.
Pointers - serious safety hazard
•	Conventional variables have many nice features:
–	unique association of memory with variables
–	distinct variables - distinct locations
–	one without the other not possible
•	Pointers provides flexibility and more control
•	But at the cost of safety
•	It is a low-level feature
•	No unique association of pointers to targets
•	More than one pointer to the same target or location
•	Pointer without location (dangling pointers)!
•	Location without any pointers too (memory leak or garbage)!
Multiple Associations
		p1 => x
		p2 => p1
		p3 => p2
		p4 => x
•	All point to the same location

Dangling Pointers
•	What is the problem with multiple associations?
•	value pointed to by p1 can be changed independently
		p1 = 10
		p2 = 17
		p1 = p1 + 1
	p1 points to a location which contains 18 and not 11
•	More serious problem:
		p1 = 10
		deallocate(p2)
		p1 = p1 + 2
•	p1 is pointing to a location which is deallocated
•	p1 is a dangling pointer
•	no control over what value the deallocated memory will contain
Memory Leak
•	Only way of accessing dynamically allocated memory is via pointers
•	Suppose there is only one pointer p pointing a location
•	nullify(p) disassociates p
•	The memory is no longer accessible
•	Memory has leaked out - memory has become garbage
•	Deallocation done before memory leaks out
•	Wastage of space
•	Separate Garbage collection phase