 Scope and linkage  Storage classes  Automatic memory  Dynamic memory  Memory Model.

Slides:



Advertisements
Similar presentations
Introduction to C Programming
Advertisements

Dynamic memory allocation
Dynamic Memory Allocation in C.  What is Memory What is Memory  Memory Allocation in C Memory Allocation in C  Difference b\w static memory allocation.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved. CHAPTER 9 MEMORY MANAGEMENT.
Dynamic Allocation Eric Roberts CS 106B February 4, 2013.
Prof. Necula CS 164 Lecture 141 Run-time Environments Lecture 8.
Chapter 7: User-Defined Functions II
ECE Application Programming Instructor: Dr. Michael Geiger Fall 2012 Lecture 31: Dynamic memory allocation.
DYNAMIC MEMORY MANAGEMENT. int x; When the source code containing this statement is compiled and linked, an executable file is generated. When the executable.
Kernighan/Ritchie: Kelley/Pohl:
Memory allocation CSE 2451 Matt Boggus. sizeof The sizeof unary operator will return the number of bytes reserved for a variable or data type. Determine:
Chapter 8 Runtime Support. How program structures are implemented in a computer memory? The evolution of programming language design has led to the creation.
Dynamic Data Structures H&K Chapter 14 Instructor – Gokcen Cilingir Cpt S 121 (July 26, 2011) Washington State University.
1 1 Lecture 4 Structure – Array, Records and Alignment Memory- How to allocate memory to speed up operation Structure – Array, Records and Alignment Memory-
Memory Arrangement Memory is arrange in a sequence of addressable units (usually bytes) –sizeof( ) return the number of units it takes to store a type.
CS 536 Spring Run-time organization Lecture 19.
Run time vs. Compile time
Chapter 6. 2 Objectives You should be able to describe: Function and Parameter Declarations Returning a Single Value Pass by Reference Variable Scope.
Run-time Environment and Program Organization
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
Pointers Applications
Storage & Linkage: Effects on Scope Rudra Dutta CSC Spring 2007, Section 001.
Review of C++ Programming Part II Sheng-Fang Huang.
CS 11 C track: lecture 5 Last week: pointers This week: Pointer arithmetic Arrays and pointers Dynamic memory allocation The stack and the heap.
Operator Precedence First the contents of all parentheses are evaluated beginning with the innermost set of parenthesis. Second all multiplications, divisions,
18-2 Understand “Scope” of an Identifier Know the Storage Classes of variables and functions Related Chapter: ABC 5.10, 5.11.
Compiler Construction
 Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class.
1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation.
Stack and Heap Memory Stack resident variables include:
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
Dynamic Memory Allocation The process of allocating memory at run time is known as dynamic memory allocation. C does not Inherently have this facility,
Pointers review Let a variable aa be defined as ‘int *aa;’, what is stored in aa? Let a variable aa be defined as ‘int ** aa;’ what is stored in aa? Why.
18. DECLARATIONS.
Pointers OVERVIEW.
Fundamentals of C and C++ Programming. EEL 3801 – Lotzi Bölöni Sub-Topics  Basic Program Structure  Variables - Types and Declarations  Basic Program.
University of Washington Today Finished up virtual memory On to memory allocation Lab 3 grades up HW 4 up later today. Lab 5 out (this afternoon): time.
ECE 103 Engineering Programming Chapter 47 Dynamic Memory Alocation Herbert G. Mayer, PSU CS Status 6/4/2014 Initial content copied verbatim from ECE 103.
Dynamic Memory Allocation. Domain A subset of the total domain name space. A domain represents a level of the hierarchy in the Domain Name Space, and.
Copyright 2005, The Ohio State University 1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation.
C Functions Three major differences between C and Java functions: –Functions are stand-alone entities, not part of objects they can be defined in a file.
CPS4200 Unix Systems Programming Chapter 2. Programs, Processes and Threads A program is a prepared sequence of instructions to accomplish a defined task.
1 Announcements Note from admins: Edit.cshrc.solaris instead of.tcshrc Note from admins: Do not use delta.ece.
ECE 103 Engineering Programming Chapter 36 C Storage Classes Herbert G. Mayer, PSU CS Status 8/4/2014 Initial content copied verbatim from ECE 103 material.
Pointers in C Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens Memory and Addresses Memory is just a sequence of byte-sized.
+ Dynamic memory allocation. + Introduction We often face situations in programming where the data is dynamics in nature. Consider a list of customers.
Functions Illustration of: Pass by value, reference Scope Allocation Reference: See your CS115/215 textbook.
+ Storage Classes and Linkage. + Introduction Scope describe the region or regions of a program that can access and identifier Variables can be shared.
MORE POINTERS Plus: Memory Allocation Heap versus Stack.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Lucas Bang Lecture 11: Pointers.
Building Programs from Existing Information Solutions for programs often can be developed from previously solved problems. Data requirements and solution.
1 This week Basics of functions Stack frames Stack vs. Heap (brief intro) Calling conventions Storage classes vs. scope Library functions Overloading.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
C Part 2 Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens The Three Attributes of an Identifier Identifiers have three essential.
Advanced Programming in C
CSE 220 – C Programming malloc, calloc, realloc.
Eine By: Avinash Reddy 09/29/2016.
Stack and Heap Memory Stack resident variables include:
Advanced Programming with C
Friend Class Friend Class A friend class can access private and protected members of other class in which it is declared as friend. It is sometimes useful.
The Three Attributes of an Identifier
Dynamic Memory Allocation
Run-time organization
Object Oriented Programming COP3330 / CGS5409
Programming and Data Structures
Memory Allocation CS 217.
Dynamic Memory A whole heap of fun….
Scope Rules Of Variables
Dynamic Memory A whole heap of fun….
The Three Attributes of an Identifier
Presentation transcript:

 Scope and linkage  Storage classes  Automatic memory  Dynamic memory  Memory Model

 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

 The scope of a variable is the region of the program in which it is visible  Block scope  Function prototype scope  File 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

 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

 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

 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

 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

 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)

 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;

 A variable has one of three storage durations  Static  Automatic  Dynamic  The duration of a variable determines its lifetime within a program

 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

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

 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

 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

 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;

 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

void f1(int x){ static int count = 0; int y = 0; … count++; } 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

The Call Stack

 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

 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

 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)

 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

 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

Let's look at a simple example of allocating memory on a stack as described previously int x = 12; x = x * 3; double d = ; int x = 12; x = x * 3; double d = ; Notice that this example ignores all sorts of complicating issues … … Why start at byte 3600? No reason, it's just an arbitrary value

 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

int main(){ int r = 3; double area = circleArea(r); int main(){ int r = 3; double area = circleArea(r); double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double square(double x){ return x * x; } double square(double x){ return x * x; } main memory start of circleArea's memory square's memory 3 3 r r radius pi x x

main memory start of circleArea's memory 9 9 sq_r r r radius pi int main(){ int r = 3; double area = circleArea(r); int main(){ int r = 3; double area = circleArea(r); double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double square(double x){ return x * x; } double square(double x){ return x * x; }

main memory r r area int main(){ int r = 3; double area = circleArea(r); int main(){ int r = 3; double area = circleArea(r); double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double circleArea(double radius){ double pi = ; double sq_r = square(radius); return sq_r * pi; } double square(double x){ return x * x; } double square(double x){ return x * x; }

 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

 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

 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

 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

 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

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int 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! (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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; where is global x visible? just in foo

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; where is global y visible? just in main

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; where is main x visible?

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; where is loop x visible?

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; what is the effect of making y static? it is not visible in other files

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; what is the effect of making foo_count static? it's lifetime is the lifetime of the program

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; } 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); } 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 Variables int x = 10; static int y = 100; // Global Variables int x = 10; static int y = 100; what is printed?

// Global Variables int 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); } // Global Variables int 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...

ignoring dynamic memory... Storage ClassDurationScopeLinkageDeclared automatic blocknonein a block registerautomaticblocknonein a block with register static externalstaticfileexternaloutside all functions static internalstaticfileinternaloutside all functions with static static no linkagestaticblocknonein a block with static

 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

 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

 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

 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

 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?

int* arr = malloc(10 * sizeof(int)); //... do stuff with arr //... and make a new, larger array arr = malloc(100 * sizeof(int)); int* arr = malloc(10 * sizeof(int)); //... do stuff with arr //... and make a new, larger array arr = 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 allocated the original 40 bytes cannot be accessed, since the program no longer records the address however, they are also unavailable for reuse, thereby causing a memory leak

 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

 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

 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

 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

 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 fails int* p; int n = ; p = (int*) malloc(n * sizeof(int)); if(p == NULL){ puts("Memory allocation failed."); exit(EXIT_FAILURE); } int* p; int n = ; p = (int*) malloc(n * sizeof(int)); if(p == NULL){ puts("Memory allocation failed."); exit(EXIT_FAILURE); } exit terminates the application

 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 type int* arr = (int *) malloc(10 * sizeof(int)); casts (converts) the pointer to void to an int pointer

static 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

 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

 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

 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

 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

This function demonstrates that static, automatic and dynamic variables are allocated space in different areas of main memory void 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); } void 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