67
Storage Classes

Storage Classes

  • Upload
    marina

  • View
    31

  • Download
    0

Embed Size (px)

DESCRIPTION

Storage Classes. Storage Classes. Scope and linkage Storage classes Automatic memory Dynamic memory Memory Model. Storage Classes. There are five storage classes That specify the lifetime and visibility of a variable This does not include dynamic memory - PowerPoint PPT Presentation

Citation preview

Page 1: Storage Classes

Storage Classes

Page 2: Storage Classes

Storage Classes

Scope and linkage Storage classes

Automatic memory Dynamic memory

Memory Model

Page 3: Storage Classes

Storage Classes

There are five storage classes That specify the lifetime and visibility of

a variable This does not include dynamic memory

The different storage classes vary in combinations of three categories Scope Linkage Duration

Page 4: Storage Classes

Scope and Linkage

Page 5: Storage Classes

Scope

The scope of a variable is the region of the program in which it is visible Block scope Function prototype scope File scope

Page 6: Storage Classes

Block Scope

A block is a region of a program enclosed in opening and closing (curly) brackets Function definitions If and switch statements Loops ...

A variable defined in a block is visible from where it is defined to the end of the block

Page 7: Storage Classes

More About Block Scope

Two variables with the same name cannot be declared in the same block But the scope of variables with the same

name may overlap▪ Only the variable with the least scope is visible

Function parameters have the same scope as the function block Even though they are declared outside

the function’s enclosing brackets

Page 8: Storage Classes

Loops and C99 Prior to the C99 standard, variables had to

be declared at the start of a block Compilers compliant with C99 allow

variables to be declared anywhere in a block Including in the initialization statement of a for

loop If a variable is declared inside a for loop its scope

is the loop To use a C99 compliant compiler in gcc use the std=c99 switch▪ gcc -o foo foo.c -std=c99

Page 9: Storage Classes

Function Prototype Scope Applies to variable names used in

function prototypes The scope only applies to the function

prototype Names given to formal parameters may

differ from the names used in the prototype

Page 10: Storage Classes

File Scope

A variable with its definition outside any function has file scope It is visible from the point it is defined to

the end of the file containing its definition

It may also be visible to other files

Page 11: Storage Classes

Linkage Linkage refers to the file visibility of variables Variables with block scope have no linkage

They are private to the block or prototype in which they are defined

Variables with file scope have either internal linkage or external linkage A variable with internal linkage can be used

anywhere inside the file in which it is declared A variable with external linkage can be used

anywhere in a multi-file program (i.e. in other files)

Page 12: Storage Classes

Linkage and static

By default, a variable with file scope has external linkage If the variable is to be visible only within

one file it should be specified as static static int answer = 42;

Page 13: Storage Classes

Storage Classes

Page 14: Storage Classes

Duration

A variable has one of three storage durations Static Automatic Dynamic

The duration of a variable determines its lifetime within a program

Page 15: Storage Classes

Static Storage

Statically stored variables last for the lifetime of a program

The number of static variables does not change as a program runs So no special system is required to

maintain them They are usually allocated space

sequentially in an area of main memory They are initialized to default values

Page 16: Storage Classes

Types of Static Variable

Static variables can have one of three types of linkage External Internal None

Page 17: Storage Classes

External Linkage

A variable declared outside any function has external linkage It can be used by other files that are part

of the same program▪ int global = 1213; //outside main

A variable with external linkage can only be defined in one file

Page 18: Storage Classes

Using External Variables

External linkage raises the spectre of name ambiguity A file could define a variable with the same

name as another file’s external variable Variables from other files should be

declared with the extern specifier extern int global; This specifies that the variable has been

declared in another file

Page 19: Storage Classes

Internal Linkage

Variables declared globally are external by default

It may be desirable to limit their scope to a single file This can be achieved by declaring the

variable with the static specifier▪ static int just_in_this_file = 211;

Page 20: Storage Classes

No Linkage

A variable declared inside a function can also be specified as static This affects its lifetime not its visibility▪ The lifetime of the variable is that of the

program It is stored in the same region of main

memory as other static variables The values of block scope static

variables are preserved between function calls Their scope is still block scope

Page 21: Storage Classes

Block Scope and Static

void f1(int x){ static int count = 0; int y = 0; … count++;}

defined once and initialized to 0

defined each time that f1 runs

adds one to count each time that f1 runs

x, count, and y all have scope only within f1

Page 22: Storage Classes

Automatic StorageThe Call Stack

Page 23: Storage Classes

Automatic Storage

Function variables and parameters use automatic storage by default And have local scope and no linkage

Automatic variables are typically managed on a call stack A section of allocated memory that

grows and shrinks as functions are called Automatic variables are not

initialized Unless done so explicitly

Page 24: Storage Classes

Functions and Memory

A variable defined in a function block only persists for the lifetime of that function call Unless it is declared as static

Consider what memory might be allocated when a function is running Memory required for the function’s data

and only required during the function call

Memory that is to persist beyond the lifetime of the function

Page 25: Storage Classes

Allocating Memory for a Call During a function call, memory can be

allocated to the function's variables But not to variables of other functions▪ Ignoring any dynamic memory allocation

Memory allocation should be fast and simple That is, the process of allocating main

memory space to a variable▪ Not the process of accessing a variable

(although that should be fast too)

Page 26: Storage Classes

Main Memory Allocation

When allocating main memory to a function it is desirable to Waste as little space as possible Minimize the amount of administration

required to track free space It is relatively easy to allocate space

to function calls sequentially If function a calls function b, then

function a is not returned to until function b is terminated

Page 27: Storage Classes

Call Stack

Automatic variables are controlled by the call stack A stack is a last-in-first-out (LIFO) data

structure A program keeps track of the stack

with two pointers One points to the base of the stack The other points to the top of the stack▪ The next free memory location▪ Stack memory is allocated sequentially

Page 28: Storage Classes

Stack Memory – Simple Example

Let's look at a simple example of allocating memory on a stack as described previously

int x = 12;x = x * 3;double d = 23.567;

Notice that this example ignores all sorts of complicating issues

… 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 …

Why start at byte 3600? No reason, it's just an arbitrary value

1236 23.567

Page 29: Storage Classes

Stack and Functions

Let's look at a more complex example of allocating memory That includes a main function and two

other function calls To make the example a bit simpler

the byte values are not shown Coloured boxes represent the memory

allocated to variables

Page 30: Storage Classes

Another Exampleint main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}

main memory

3 3 3.1415

start of circleArea's memory

square's memory3

r radius pi

x

Page 31: Storage Classes

Another Example

main memory

3 3 3.1415

start of circleArea's memory

9sq_rr radius pi

int main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}

Page 32: Storage Classes

Another Example

main memory

3 28.274r area

int main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}

Page 33: Storage Classes

Pushing and Popping

Function parameters and function variables are pushed onto the stack And the pointer to the top of the stack is

moved up by the size of each variable When a function terminates, the top

of the stack is reset to its original position Releasing memory assigned to the

function

Page 34: Storage Classes

Register Variables

C supports the register specifier for declaring variables Register variables are automatic so have▪ Lifetime over the life of the block,▪ Local scope, and▪ No linkage

Register is a hint to the compiler to assign the variable to a register Allowing the CPU to access it quickly

Page 35: Storage Classes

Compiler Hints

Specifying a variable as register is a request to the compiler so may be ignored If the registers are full Or the variable type does not fit in a

register Modern compilers may be able to

assign variables to registers on their own e.g. for loop indexes ▪ As they are required frequently

Page 36: Storage Classes

Stack Overflow

A compiler sets aside a fixed portion of main memory for the call stack If this is all used up by function calls

then a stack overflow occurs Resulting in termination of the

application Some recursive algorithms are prone

to stack overflow

Page 37: Storage Classes

Functions and Linkage

By default functions have external linkage Functions cannot be declared inside one

another so exist over the life of a program

Functions can be declared static to specify that they have internal linkage And can only be called in that file Allowing another function with the same

name to be used in another file

Page 38: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh! (global)x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh! (global)printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

Page 39: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh! (global)x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh! (global)printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

where is global x visible?

just in foo

Page 40: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh! (global)x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh! (global)printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

where is global y visible?

just in main

Page 41: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

where is main x visible?

Page 42: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

where is loop x visible?

Page 43: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

what is the effect of making y static?

it is not visible in other files

Page 44: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

what is the effect of making foo_count static?

it's lifetime is the lifetime of the program

Page 45: Storage Classes

Scope Quiz

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

// Global Variablesint x = 10;static int y = 100;

what is printed?

Page 46: Storage Classes

Scope Quiz

// Global Variablesint x = 10;static int y = 100;

int main(){

int i;int x = 1;printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);printf("\n.. and into loop (y += i, x += i) ...\n\n");for(i=0; i < 4; i++){

int x = 1000;y = y + i; //aargh!x = x * i;printf("%9s%04d %12s%04d ", "loop i = ", i, "loop x = ", x);printf("%12s%04d\n", "global y = ", y);foo(x);

}printf("\n.. and out of loop ...\n\n");printf("%9s%04d %12s%04d\n", "main x = ", x, "global y = ", y);foo(x);return 0;

}

void foo(int y){

static int foo_count = 0;foo_count++;y++;x++; //aargh!printf("%9s%04d %12s%04d ", "foo y = ", y, "foo_count = ", foo_count);printf("%12s%04d\n", "global x = ", x);

}

what is printed ...

Page 47: Storage Classes

Storage Class Combinations

ignoring dynamic memory ...

Storage Class

Duration

Scope

Linkage

Declared

automatic automatic

block none in a block

register automatic

block none in a block with register

static external

static file external

outside all functions

static internal static file internal

outside all functions with static

static no linkage

static block none in a block with static

Page 48: Storage Classes

Dynamic Memory

Page 49: Storage Classes

Dynamic Memory Introduction The duration of variables allocated in

automatic or static memory is fixed The size of such variables is dependent

on type and is also fixed It may be useful to determine the

space to be allocated to a variable at run-time To avoid wasting space where the space

requirements may vary considerably

Page 50: Storage Classes

Dynamic Memory

Dynamic memory is allocated from a different area of memory than the stack This area of memory is referred to as the

free store or the heap Like stack memory the size is fixed, and

is (of course) finite

Page 51: Storage Classes

Allocating Dynamic Memory Dynamic memory can be allocated at

runtime Using malloc to request memory of a given size The malloc function takes a single argument▪ The number of bytes to be allocated

Memory allocated with malloc remains allocated until it is released It is not limited to the lifetime of the block in

which it is allocated Memory is released by calling free

Page 52: Storage Classes

More About Pointers

In addition to allocating memory, malloc returns the address of this memory The address should be assigned to a

pointer variable Dynamic memory is often used to

create dynamic arrays For example create an array of ten

integers▪ int* arr = malloc(10 * sizeof(int));▪ The address returned by malloc is assigned to

arr

Page 53: Storage Classes

Dynamic Arrays

Arrays assigned to pointers may be used just like regular (static) arrays The elements can be accessed using an

index There is one major difference

between dynamic arrays and static arrays A pointer can be assigned a new array But what happens to the old array?

Page 54: Storage Classes

Creating New Arraysint* arr = malloc(10 * sizeof(int));// ... do stuff with arr// ... and make a new, larger arrayarr = malloc(100 * sizeof(int));

allocates 40 bytes in the heap

allocates another 400 bytes in the heap, it does not re-use the 40 bytes that were previously allocatedthe original 40 bytes cannot be accessed, since the program no longer records the addresshowever, they are also unavailable for reuse, thereby causing a memory leak

Page 55: Storage Classes

Memory Leaks

A memory leak occurs when dynamic memory is allocated but is not de-allocated When it is no longer required

Dynamic memory that is not de-allocated is unavailable until the program terminates Or even longer in some (usually older)

operating systems Large memory leaks may affect the

performance of applications

Page 56: Storage Classes

Freeing Dynamic Memory Any dynamic memory that is

allocated by a program should be de-allocated By calling free▪ The free function takes a single argument,

the pointer to the memory that is to be de-allocated

Every use of malloc should be matched by a call to free When the allocated dynamic memory is

no longer required

Page 57: Storage Classes

Lifetime of Dynamic Memory Unlike static or automatic memory

the lifetime of dynamic memory is not fixed It is dependent on when the memory is

first allocated and when it is released The lifetime of a variable created in

dynamic memory is between the calls to malloc and free

Page 58: Storage Classes

Allocating Memory with calloc The calloc function can also be used

to allocate dynamic memory It takes two arguments, the size of the

array and the size of the array type▪ int* arr = calloc(10, sizeof(int));

Unlike malloc, calloc also sets all of the bits in the allocated memory to 0

The free function is used to de-allocate memory allocated with calloc

Page 59: Storage Classes

Out of Memory

Dynamic memory can be exhausted To make memory allocation safe it is

good practice to ensure that allocation succeeds Both malloc and calloc will return the

NULL pointer if allocation failsint* p;int n = 10000000;p = (int*) malloc(n * sizeof(int));if(p == NULL){

puts("Memory allocation failed.");exit(EXIT_FAILURE);

}exit terminates the application

Page 60: Storage Classes

ANSI C Standard and malloc Under the ANSI C standard both

calloc and malloc return pointers to void A generic pointer

It is therefore good practice to cast the pointer returned by malloc to the correct typeint* arr = (int *) malloc(10 * sizeof(int));

casts (converts) the pointer to void to an int pointer

Page 61: Storage Classes

Memory Model

Page 62: Storage Classes

static

Storage

code storage

automatic

dynamic

storage space for program instructions

global variables and variables declared as static

function calls, local variables and function parameters

dynamically allocated variables, addresses are assigned to pointers

Page 63: Storage Classes

Static Memory

Used for global variables and variables that are explicitly declared as static With the keyword static Exist for the lifetime of the program

Local, static variables are declared and initialized once Should be used for variables that are to

persist over the life of the program

Page 64: Storage Classes

Automatic Memory

Used for most local variables declared in a block or function header Exist only for the lifetime of the block The most common method of variable

storage Variables can be explicitly declared as

automatic by using the auto keyword▪ To indicate that the variable should not be

changed to some other storage class Typically allocated on a call stack

Page 65: Storage Classes

Dynamic Memory

Used for variables whose size or lifetime can only be determined at run-time Allows arrays of varying size to be assigned

to one pointer variable (over time) The allocation of dynamic memory is

controlled by function calls A dynamic variable’s lifetime starts with a

call to malloc (or calloc) and ends with a call to free▪ Or when the program terminates

Page 66: Storage Classes

Memory Model Summary

Static, automatic and dynamic memory are different regions of RAM Variables in static memory require the

least amount of overhead Automatic variables require more

overhead▪ Since information about function calls needs

to be maintained Variables in dynamic memory require

the most overhead

Page 67: Storage Classes

Memory TestThis function demonstrates that static, automatic and dynamic variables are allocated space in different areas of main memoryvoid memoryTest(){

static int x;int y = 0;int* p = malloc(4 * sizeof(int));double* q = calloc(10, sizeof(double));char* s = "albatross";

printf("static (s:albatross): %x\n", s);printf("static (&x): %x\n", &x);printf("automatic (&y): %x\n", &y);printf("automatic (&p): %x\n", &p);printf("automatic (&q): %x\n", &q);printf("automatic (&s): %x\n", &s);printf("dynamic (p): %x\n", p);printf("dynamic (q): %x\n", q);

}

string literals are stored in static memory