1.08k likes | 1.23k Views
Lecture 13 - Review. Review. L ecture 1 - Address Map - Global vs Local. Pointer. int var (var is a variable and occupies 4 bytes ) int *var (*var is a pointer that points to an integer). Example. Example 1 *. Pointer to an integer. int var = 108; int *varpointer;
E N D
Pointer • int var (var is a variable and occupies 4 bytes ) • int *var (*var is a pointer that points to an integer)
Example 1 * Pointer to an integer • int var = 108; • int *varpointer; • &varpt = var; (*varpt = 123)
Example 2 Point to location 0x0012FF7C Value is 0x61 = ‘a’
Array and Pointer * • char a[10]=“1234567890”; • a[0] =“1”; • a[1] =“2”; • char *ptr; • ptr = &a; (or just a in C); • *ptr -> 1 (a[0]) • *(ptr + 1) ->2 (a[1]) • array[i] * (array + i) &array[i] array + i array[i + j] * (array + i + j) &array[i + j] array + i + j Same result, different expression
Multi-Dimensional Arrays – pointer of pointer • array2[7][10] or **array2 5 6 0 1 2 3 4 0 1 2
Naughty Pointers • The value pointed by pointer is modified. • It will destroy the program and is not recommended. • However, if you can master pointer, you can write a very elegant program.
Summary You have to rotate the data 0x00000003 • Integer : 4 bytes such as int a = 3; • 0x0065FDF1:03 • 0x0065FDF2:00 • 0x0065FDF3:00 • 0x0065FDF4:00
Summary Not used • Short: two bytes • Short a = 3; • 0x0065FDF3: 03 • 0x0065FDF4: 00 • Short b = 4; • 0x0065FDF0: 04 • 0x0065FDF1: 00 As short uses 2 bytes, remaining two bytes in memory 0x0065FDF2 (0xCC) and 0x0065FDF1 (0xCC) are not used
Example – abc program name • #include <stdio.h> int first; int second; void callee ( int first ) { int second; second = 1; first = 2; printf("callee: first = %d second = %d\n", first, second); } int main (int argc, char *argv[]) { first = 1; second = 2; callee(first); printf("caller: first = %d second = %d\n", first, second); return 0; } Same variable “second”, but different memory location DOS>abc 12 34 Here, argc = 3, argv[0] = abc argv[1]= 12 argv[2] =34
Example (passed by pointer) * • void callee ( int * first ) //not a variable, but an address { int second; second = 1; *first = 2; printf("callee: first = %d second = %d\n", *first, second); } int main (int argc, char *argv[]) { first = 1; second = 2; callee(&first); //passed by address --- printf("caller: first = %d second = %d\n", first, second); return 0; } Content by address
Diagram - stack push (create) Before After
Diagram - stack pop (return) Before After
The CPU also Has Memory • The CPU also maintains its own banks of memory called registers. • They temporarily hold the data • As a result, the program is faster. register Memory hierarchy Cache memory Main memory Disk
Bit Operations • AND & • OR | • ONE'S COMPLEMENT ~ • EXCLUSIVE OR ^ • SHIFT (right) >> • SHIFT (left) <<
Operation - examples • AND 1 & 1 = 1; 1& 0 = 0 • OR 1 |1 = 1; 1| 0 = 1; 0|0 = 0 • ~ 0 =~1; 1 =~0; • ^ 0^ 0 = 0; 1^1 = 0; 1^0 =1; 0^1 = 1 • >> 0x010 = 0x001 <<1 • << 0x001 = 0x010 >>1
One’s complement • 1111 0010 (0xf2)-------------- ~0000 1101 (0x0d) • char c = 0xf2;char e = ~c; //e is 0x0d
EXCLUSIVE OR • 1111 0010 (0xf2)1111 1110 (0xfe)-------------- (^) 0000 1100 (0x0c)char c = 0xf2;char d = 0xfe;char e = c ^ d; //e is 0x0c
SHIFT >> (right) by one bit • 1111 0010 (0xf2)>> 1 (shift right by one bit)--------------------- • 0111 10001 (0x79)char c = 0xf2;char e = c >>1; //e is 0x79
SHIFT << (left) by one bit • 1111 0010 (0xf2)<< 1 (shift right by one bit)--------------------- • 1110 0100 (0xe4)char c = 0xf2;char e = c <<1; //e is 0xe4
SHIFT << by two bits • 1111 0010 (0xf2)>> 2 (shift right by one bit)--------------------- • 1100 1000 (0xc8)char c = 0xf2;char e = c <<2; //e is 0xc8
Expression • 1 bit sign bit, 8 bit exponent, and 23 bit Mantissa (total 32 bits) • -1^Sign * 2^(Exponent - 127) * (1 + Mantissa * 2^-23) • Zero, sign bit is 0, Negative, sign bit is 1 • Exponent is unsigned, minus 127. That is if the value is 128, it means 128 – 127 = 1, if the value is 256, it means 256 – 127 = 128, or the value is zero, it means 0 – 127 = -127.
Example • 2.5 (floating point) • 0100 0000 0010 0000 0000 0000 0000 0000 • Sign: positive (1) • Exponent : 1000 0000 : 128 (128 – 127 = 1) • Mantissa: 1. 010 0000 0000 0000 0000 0000, 1.25 • Result 1 x 1.25 x 2^1 = 2.5
String • Is an array of character and is terminated by a null character (0x00) • char a[4] = “Hi?”; • a[0] = H; • a[1] = I; • a[2] =?; • a[3] = 0x00 Incorrect declaration: char char[3] = “Hi?”, as 0x00 is missing
An example • struct { • char a, b, c, cc; • int i; • double d; • } mystruct; • Name is mystruct
Static Allocation • The word static (fix) refers to things that happen at compile time (compile) and link (link) time when the program is constructed. • For example, you can define • char a[9] =“12345678”; //assign 9 bytes for array a • The compiler will assign 9 bytes during compilation • Linker will assign the correct address for array a • You cannot change it even you think you need 10 bytes while running this program
An example int my_var[128]; // a statically allocated variable static bool my_var_initialized = false; //static declaration int my_fn(int x) { if (my_var_initialized) return; my_var_initialized = true; for (int i = 0; i < 128; i++) my_var[i] = 0; } Initially, it is false
Dynamic allocation • Limitations of Static Allocation • If two procedures use a local variable named i, there will be a conflict if both i's are globally visible. • If i is only declared once, then i will be shared by the two procedures. One might call the other, even indirectly, and cause i to be overwritten unexpectedly. • It would be better if each procedure could have its own copy of i.
Grab memory • To grab memory, we have to use malloc(size). For example • ptr = malloc(4) will return a pointer with memory size of 4 bytes • ptr = malloc(4*int) will return a pointer with 16 bytes = 4 x 4 (integer) = 16 bytes • malloc(4*long) will return a pointer with 16 bytes = 4 x 4 (long) = 16 bytes • free(ptr), free this pointer to the memory
Fragmentation – holes Although it has memory
Example of First fit I need 20K bytes 15K 25K 45K 20K free blocks
Example of Best fit I need 20K bytes 15K 25K 45K 20K free blocks
Example of Worst fit I need 20K bytes 15K 25K 45K 20K free blocks
Block sizes – the size to hold the data for users’ usage • The standard method for determining the size of a block, given a pointer to the block, is to store its size in the word before the pointer. • Here, the memory block that can be used is 16 bytes, the block size is 20 bytes including 4 bytes for the size Only 16 bytes
Determine the size size = ((int *) ptr)[-1]; // read integer before the memory block correct_size = size & ~3; // clear the lower 2 bits free = size & 1; // get low-order bit • Note that it uses [-1] to point to location before the pointer (location that contains block size) • As the size is a multiple of 4, it clears the lowest two bits (3 =0000 0000 0000 0011 (hex), ~3 = 1111 1111 1111 1100 • Free means the block can be used by user (binary 1)
Splitting a Free Block • The heap is normally initialized to look like one giant free block. (40 bytes) • When allocations occur, it would be wasteful to return a large block of free memory when a small one would do just as well. (I need 8 bytes, no point to return 40 bytes) • Therefore, the memory allocator will typically split a block if the block size is larger than the requested size. (12 allocated and 28 free)
Common bug in scanf int i; double d; scanf("%d %g", i, d); // wrong!!! // here is the correct call: scanf("%d %g", &i, &d); • Note that you should supply the address rather than the variable • Use &i; instead of i • It is important in your exam.
Overwriting Memory #define array_size 100 int *a = (int *) malloc(sizeof(int *) * array_size); for (int i = 0; i <= array_size; i++) a[i] = NULL; • Here, i will be incremented from 0 to array_size, not array_size – 1; • The solution is • ; i < array_size; not • ; i <= array_size;
Memory bug #define array_size 100 int *a = (int *) malloc(array_size); a[99] = 0; // this overwrites memory beyond the block • Here, the memory allocated is 100 bytes, not 400 bytes and a[] is defined as array pointer • The solution is: int *a = (int *) malloc( array_size* sizeof(int));
String must be terminated by 0x00 char *heapify_string(char *s) { int len = strlen(s); char *new_s = (char *) malloc(len); strcpy(new_s, s); return new_s; } • String must be terminated by 0x00; • The solution is: char *new_s = (char *) malloc(len + 1); By 0x00
Memory leaks • The memory that is on longer used is not returned to the memory pool. • The result is that the system will run out of memory. • The failure to deallocate (free) a block of memory when it is no longer needed is often called a memory leak Do not return the memory block to the pool