Memory Arrangement Memory is arrange in a sequence


![Arrays Defines a block of consecutive cells int main() { int i; int a[4]; Arrays Defines a block of consecutive cells int main() { int i; int a[4];](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-3.jpg)
![Arrays • C does not provide any run time checks int a[4]; a[-1] = Arrays • C does not provide any run time checks int a[4]; a[-1] =](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-4.jpg)

![Array Initialization int int arr[3] arr[4] arr[2] = = {3, {3, 4, 4, 5}; Array Initialization int int arr[3] arr[4] arr[2] = = {3, {3, 4, 4, 5};](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-6.jpg)







![Pointers & Arrays int *p; int a[4]; p = &a[0]; *(p+1) = 1; // Pointers & Arrays int *p; int a[4]; p = &a[0]; *(p+1) = 1; //](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-14.jpg)
![Pointers & arrays Arrays are essentially constant pointers int *p; int a[4]; p = Pointers & arrays Arrays are essentially constant pointers int *p; int a[4]; p =](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-15.jpg)
![Pointers & Arrays int foo( int *p ); and int foo( int a[] ); Pointers & Arrays int foo( int *p ); and int foo( int a[] );](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-16.jpg)
![Pointer Arithmetic int a[4]; int *p = a; char *q = (char *)a; // Pointer Arithmetic int a[4]; int *p = a; char *q = (char *)a; //](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-17.jpg)
![Pointer arithmetic int Find. First. Non. Zero( int a[], int n ) { int Pointer arithmetic int Find. First. Non. Zero( int a[], int n ) { int](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-18.jpg)





![C String Example char* text = “string”; // means text[5] == ‘g’ and text[6] C String Example char* text = “string”; // means text[5] == ‘g’ and text[6]](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-24.jpg)
![C Strings More Examples • Recall arrays are essentially constant pointers. char txt 1[] C Strings More Examples • Recall arrays are essentially constant pointers. char txt 1[]](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-25.jpg)























- Slides: 48

Memory Arrangement • Memory is arrange in a sequence of addressable units (usually bytes) – sizeof( <Type> ) return the number of units it takes to store a type. – sizeof(char) = 1 – sizeof(int) = 4 (on most of our machines)

Memory int main() { char c; int i, j; double x; … c i j x
![Arrays Defines a block of consecutive cells int main int i int a4 Arrays Defines a block of consecutive cells int main() { int i; int a[4];](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-3.jpg)
Arrays Defines a block of consecutive cells int main() { int i; int a[4]; … i a[0] a[1] a[2] a[3]
![Arrays C does not provide any run time checks int a4 a1 Arrays • C does not provide any run time checks int a[4]; a[-1] =](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-4.jpg)
Arrays • C does not provide any run time checks int a[4]; a[-1] = 0; a[4] = 0; This will compile and run (no errors) …but can lead to unpredictable results. • It is the programmer’s responsibility to check whether the index is out of bounds…

Arrays • C does not provide array operations int … a = if( … a[4]; b; // illegal a == b ) // illegal
![Array Initialization int int arr3 arr4 arr2 3 3 4 4 5 Array Initialization int int arr[3] arr[4] arr[2] = = {3, {3, 4, 4, 5};](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-6.jpg)
Array Initialization int int arr[3] arr[4] arr[2] = = {3, {3, 4, 4, 5}; 5}; // // Good - The same Good - The last is 0 Bad int arr[2][3] = {{2, 5, 7}, {4, 6, 7}}; // Good int arr[2][3] = {2, 5, 7, 4, 6, 7}; // Good - The same int arr[3][2] = {{2, 5, 7}, {4, 6, 7}}; // Bad int arr[3]; arr = {2, 5, 7}; // Bad - array assignment only in initialization

Pointers int main() { int i, j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; i j x 1

Pointers int main() { int i, j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; i j x 1 0 x 0100

Pointers int main() { int i, j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; i j x 1 0 x 0100

Pointers int main() { int i, j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; i j x 1 0 x 0100 1 0 x 0104

Pointers int main() { int i, j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; i j x 1 0 x 0100 3 0 x 0104

Pointers • Declaration <type> *p; p points to objects of type <type> • Reference &x - the pointer to x • De. Reference *p = x; y = *p; *p refers to the object p points to

Example – the swap function Does nothing void swap(int a, int b) { int temp = a; a = b; b = temp; } …. int main() { int x, y; x = 3; y = 7; swap(x, y); // now x==3, y==7 …. Works void swap(int *pa, int *pb) { int temp = *pa; *pa = *pb; *pb = temp; } …. int main() { int x, y; x = 3; y = 7; swap(&x, &y); // x == 7, y == 3 …
![Pointers Arrays int p int a4 p a0 p1 1 Pointers & Arrays int *p; int a[4]; p = &a[0]; *(p+1) = 1; //](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-14.jpg)
Pointers & Arrays int *p; int a[4]; p = &a[0]; *(p+1) = 1; // assignment to a[1]! p a[0] a[1] a[2] a[3]
![Pointers arrays Arrays are essentially constant pointers int p int a4 p Pointers & arrays Arrays are essentially constant pointers int *p; int a[4]; p =](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-15.jpg)
Pointers & arrays Arrays are essentially constant pointers int *p; int a[4]; p = a; // same as p = &a[0] p[1] = 102; // same as *(p+1)=102; *(a+1) = 102; // same p++; // p == a+1 == &a[1] a = p; // illegal a++; // illegal
![Pointers Arrays int foo int p and int foo int a Pointers & Arrays int foo( int *p ); and int foo( int a[] );](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-16.jpg)
Pointers & Arrays int foo( int *p ); and int foo( int a[] ); Are declaring the same interface • In both cases, a pointer to int is being passed to the function foo
![Pointer Arithmetic int a4 int p a char q char a Pointer Arithmetic int a[4]; int *p = a; char *q = (char *)a; //](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-17.jpg)
Pointer Arithmetic int a[4]; int *p = a; char *q = (char *)a; // Explicit cast // p and q point to the same location p++; // increment p by 1 int (4 bytes) q++; // increment q by 1 char (1 byte) a[0] q a[1] p a[2] a[3]
![Pointer arithmetic int Find First Non Zero int a int n int Pointer arithmetic int Find. First. Non. Zero( int a[], int n ) { int](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-18.jpg)
Pointer arithmetic int Find. First. Non. Zero( int a[], int n ) { int *p; for( p = a; (p < a+n) && ((*p) == 0); p++ ) ; return p-a; } Same as int Find. First. Non. Zero( int a[], int n ) { int i; for( i = 0; (i < n) && (a[i] == 0); i++ ) ; return i; }

void *p defines a pointer to undetermined type int j; int *p = &j; void* q = p; // no cast needed p = (int*)q ; // cast is needed

NULL pointer • Special value: uninitialized pointer int *p = NULL; … if( p != NULL ) { … }

Strings in C

C String char: usually 1 byte. An Integer (ASCII code). String: An array of characters. char* txt 1 = “text”; char txt 2[] = “text”; char txt 3[] = {‘t’, ’e’, ’x’, ’t’, ’ ’}; t e x t

C Strings • Strings are always terminated by a null character, (a character with integer value 0 equals to the special character ‘ ’). • There is no way to enforce it when you do your own strings →: – Remember it’s there – Allocate memory for it
![C String Example char text string means text5 g and text6 C String Example char* text = “string”; // means text[5] == ‘g’ and text[6]](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-24.jpg)
C String Example char* text = “string”; // means text[5] == ‘g’ and text[6] == ‘ ’ // 7 chars are allocated!
![C Strings More Examples Recall arrays are essentially constant pointers char txt 1 C Strings More Examples • Recall arrays are essentially constant pointers. char txt 1[]](https://slidetodoc.com/presentation_image_h2/5392e6e8d7d1d8e7dbc3c303cdc9467e/image-25.jpg)
C Strings More Examples • Recall arrays are essentially constant pointers. char txt 1[] = “text”; char* txt 2 = “text”; int i = strlen(txt 1); // i = 4, same for strlen(txt 2); txt 1[0] = ‘n’; //”next”; txt 1 = txt 2; // illegal ! txt 2 = txt 1; //legal. now txt 2 points to the same string.

C Strings Manipulation • To manipulate a single character use the functions defined in ctype. h #include <ctype. h> • Manipulation of Strings is done by including the string. h header file #include <string. h> • Read manual pages: string and isalpha

Test yourself • What does this do? What are the assumptions ? int f(const char * p, const char * q) { for(; *p && *p ==*q; p++, q++) ; return *p-*q; }

Memory Organization • During run time, variables can be stored in one of three “pools” – Stack – Static heap – Dynamic heap

Stack • Maintains memory during function calls – Argument of the function – Local variables – Call Frame • Variables on the stack have limited “life time”

Stack - Example int foo( int a, double f ) { int b; … } <call> a f b

Stack - Example int foo( int a, double f ) { int b; … { int c; … } <call> a f b

Stack - Example int foo( int a, double f ) { int b; … { int c; … } <call> a f b c

Stack - Example int foo( int a, double f ) { int b; … { int c; … } <call> a f b c

Stack - Example int foo( int a, double f ) { int b; … { int c; … } <call> a f b c

Stack – recursive example void foo( int depth ) { int a; if( depth > 1 ) foo( depth-1 ); } int main() { foo(3); <call> depth a

Stack – errors? void foo( int depth ) { int a; if( depth > 1 ) foo( depth ); } Will result in run time error: out of stack space

Static heap • Memory for global variables #include <stdio. h> const int List. Of. Numbers. Size = 1000; int List. Of. Numbers[List. Of. Numbers. Size]; int main() { …

Static heap • Variables on the static heap are defined throughout the execution of the program • Memory on the static heap must be defined at compile time

Static heap: reverse example Example: program to reverse the order of lines of a file To this task, we need to • read the lines into memory • Print lines in reverse How do we store the lines in memory?

Static heap: reverse example const int Line. Length = 100; const int Number. Of. Lines = 10000; char Lines[Number. Of. Lines][Line. Length]; … int main() { int n = Read. Lines(); for( n-- ; n >= 0; n-- ) printf(“%sn”, Lines[n]); }

Static heap: reverse example This solution is problematic: • The program cannot handle files larger than these specified by the compile time choices • If we set Number. Of. Lines to be very large, then the program requires this amount of memory even if we are reversing a short file Want to use memory on “as needed” basis

Dynamic Heap • Memory that can be allocated and freed by the program during run time • The program controls how much is allocated and when • Limitations based on run-time situation – Available memory on the computer

Allocating Memory from Heap void *malloc( size_t Size ); • Returns a pointer to a new memory block of size Size • Returns NULL if it cannot allocate memory of this size

Example: strdup Function to duplicate a string: char * strdup( char const *p ) { int n = strlen(p); char* q =(char*)malloc(sizeof(char)*(n+1)); if( q != NULL ) strcpy( q, p ); return q; } This function is part of the standard library

Memory Management <call> p q void foo( char const* p ) { char *q = strdup( p ); // do something with q … The allocated memory remains in use • cannot be reused later on Heap } ‘a’ ‘b’ ‘ ’

De-allocating memory void free( void *p ); • Returns the memory block pointed by p to the pool of unused memory • No error checking! – If p was not allocated by malloc, undefined behavior

Example of free void foo( char const* p ) { char *q = strdup( p ); // do something with q free(q); } This version frees the allocated memory

Further Knowledge Read manual page of • malloc • calloc • realloc • free