## Introduction

• View addresses of local variables and heap variables
• Stack protocol for locals
• Heap reuse

• See two ways to view addresses: attribute 'address and values of access types

• Also consider pointers in other languages

• How to print, using Address Attribute:
i: Integer;
...

• Printing Values of Access Types:
• We will convert a value of an access type into a type that we can print

## Printing Values of Access Types - SKIP

### Printing Access Types

• How do we print values of Access Types,

• Problem: No I/O routine for them

• Possible solution: Convert access type to an int
• No - Integer range is about 2^-31 .. 2^31. Address range is about 0 .. 2^32.

• Solution: Define a type for 32-bit addresses and convert an access type to that type
• Use modular types for the type
• Use Unchecked_Conversion to convert an access type into the modular type

### Modular Types

• Example modular type: minutes.adb (prettified)

• Values of type minuteType range from 0 to 59 and they wrap
• Arithmetic for type minuteType wraps
• procedure minutes is

type MinuteType is mod 60;

package Minute_IO is new Text_IO.Modular_IO (Num => MinuteType);
use Minute_IO;

m: MinuteType;

begin
m := 50;
m := m + 20;
put(m);    -- Outputs 10

• Side Note: Modular types allow some bitwise operations such as and, or, not, xor:
•     type Unsigned_Byte is mod 256;
u: Unsigned_Byte := 2#0011_0101#
v: Unsigned_Byte := 2#1111_0000#
w: Unsigned_Byte := u and v;

• Our motivation for looking at modular types: define a type that will allow us to print addresses
• Addresses are 32 bits long (on a 32 bit machine)
• Addresses take values from 0 to 2**32 - 1
• The largest address (2**32-1) is 2#1111_1111_1111_1111_1111_1111_1111_1111# in binary
• Ada.Integer_Text_IO would print 2#1111_1111_1111_1111_1111_1111_1111_1111# as -1 rather than as a large integer

• We use a Modular Type to hold 32 bit addresses
•  type AddressType is mod 2**32;
• We use generic package modular_io to define an io package for AddressTypes

### Modular Types in Other Languages

• Other languages have something similar to modular types: unsigned types
• C: unsigned int, unsigned char
• Java: char

• Examples:
•     // Java
char c;
c = 97;  // Ascii 'a'
c = -1;  // Error

// C
unsigned int ui;
ui = -1; // Compiles fine!
// can print ui as

### Converting Pointers to Our Address Type

• Generic function Unchecked_Conversion allows a program to ignore type rules:
• Use Unchecked_Conversion to convert from a pointer type to a modular type

• Example: Create Copy which takes an IntPointer and returns an AddressType
•         type IntPointer is access Integer;

function Copy is
new Unchecked_Conversion (Source => IntPointer,

a: IntPointer;
...
b := Copy(a)

• Variable a is copied to b, even though types don't match

• Shows Modular Type and Unchecked_Conversion
• Shows heap addresses and reuse of heap locations

## Pointing to Variables on the Stack

### Pointing to Variables on the Stack

• Attribute 'access returns an access type value that points to a variable

• Special rules are required for pointing to a local variable:
• A local variable with a pointer to it must be marked as aliased
• The type IntPointer must be defined as an access all Integer

• Why: what happens here:
•             type Int_Pointer is access all Integer;  -- all allows pointing to locals

loc: aliased integer;  -- allow pointers to loc
begin
ip := loc'access;

an_ip: Int_Pointer;
begin
put(an_ip.all);

• Remember: local variables are allocated on the stack
• The code above will not compile: non-local pointer type points to local variable
• See below for C code

### Examples

• These examples show:
• Printing values of access types
• Pointers to local variables

• Example 1: aliasedlocal.adb (and prettified)
• Shows addresses of locals decreasing and of heap increasing
• Also shows creation and use of a dangling reference and reallocation to same location

• Example 2: aliasedlocal2.adb (and prettified)
• Shows addresses of locals in the main procedure and in a called procedure:

• Another Example): uninitlocals.adb (and prettified)
• Variable b in putlocaladdr2 is uninitialized, but it uses the value left in memory by putlocaladdr1

## Pointers in Other Languages

### Introduction

• In java and ada we get automatic dereferencing of pointer variables; in other languages (eg c and c++), dereferencing is not necessarily automatic.

• As an example, we will look at procedure swap in several languages

### Swap in Ada and Java

•         procedure swap(i, j: in out integer) is
t: constant integer := i;
begin
i := j;
j := t;
end swap;
...
i := 3; j := 4;
swap(i, j);
put(i); put(j);

• Swap in Java:
•     // Swap routine in Java
swap(int i, int j){
int temp = i;
i = j;
j = temp
S.o.p(i);
S.o.p(j);
}

// Client code:
int i=5, j=6;
...
swap(i, j);   // Like in parameters
S.o.p(i);
S.o.p(j);

### Pointers in C - Swap

• C makes heavy use of pointers.  For example, it uses pointers to get the effect of out and in out parameters.
• C uses int *p to denote that p points to an integer
• C uses *p to dereference p
• C uses &i to give the address of i
• Swap example:
•     // Swap routine in C
swap(int *ip, int *jp){   // ip and jp are pointers to integers
int temp = *ip;        // Explicit dereference of pointer ip
*ip = *jp;
*jp = temp
}

// Client code:
int i = 5, j = 6;
...
swap(&i, &j);   // Pass explicit pointers to i and j

• In C, pointers are also used to access arrays (example below).

### Pointers in C++ - Swap

• C++ is similar to C with pointers.  C++ does allow reference mode parameters that are effectively in out mode parameters. They are automatically passed by address and have automatic dereferencing.
•     // Swap routine in C++
swap(int &ip, int &jp){   // i and j are reference parameters
int temp = ip;         // Automatic dereference of pointer ip
ip = jp;
jp = temp
}

// Client code:
int i=5, j=6;
...
swap(i, j);   // Pass implicit pointers to i and j

### Pointers in C - Arrays

• C arrays:
•     int a[] = {11, 22, 33};

// Change a[2]
a[2] = 44;

// Change a[2]
*(a+2) = 55;   // * means dereference.  +2 means 2 words

### Why Pointers

• Creating dynamic structures
• Size can grow and shrink as needed
• Examples: Dynamic stacks and queues

• Allocating heap memory
• Java objects (of any size) are on heap

• Accessing variable-sized heap objects with constant sized references
• Makes OO and polymorphism possible
• Ada objects use pointers to avoid size issue

• Heap objects can change size
• Example: Java strings (s="abc"; s="de";)
• Example: Java ArrayList
• Allocate a certain size
• When run out of space, allocate more (may copy into new space)
• Known as amortized doubling

• Parameter passing
• Can pass large or unknown-size parameters by copying reference instead of value