Dynamic Memory Allocation and Command-line Arguments CSC209: Software Tools and Systems Programming Furkan Alaca & Paul Vrbik University of Toronto Mississauga https://mcs.utm.utoronto.ca/~209/ Week 3 1 / 39
Let s quickly review some definitions. Definition (Byte) One byte is eight bits. 1 byte =. Type char int long int long long int sizeof bytes* 1 (8-bit) 4 (32-bit) 8 (64-bit) 8 (64-bit) *Using GNU C compiler (gcc) on a 64-bit system, with std=gnu11 (default). These values can be found in the GNU C Reference Manual: https://www.gnu.org/software/gnu-c-manual/ 2 / 39
Notation On most of your systems, pointers will be 64-bits in size (8 bytes) For simplicity, we ll draw diagrams with 16-bit addresses (2 bytes). Imagine the leading bits are zeros. Each hex digit represents 4 binary digits In memory diagrams, pay attention to whether each cell represents a single byte or multiple (e.g., 4) bytes Tutorial on binary, decimal, and hexadecimal notation: https://linux.die.net/man/1/bin_dec_hex 3 / 39
When we initialize a variable, hardware memory is electrically modified 1 int x; 2 x = 23; int x 0xF000 0xF001 0xF002 0xF003 we denote this by writing int x 0xF000 23 4 / 39
Notation 0xF120 (char [4]) y 0xF124 "ABCD" 0xF128 0xF12C (char*) x 0xF130 &y 0xF134 Means: 0xF120 0xF124 "ABCD" 0xF128 0xF12C 0xF130 0xF124 0xF134 5 / 39
Exercise 0xF120 (char [4]) y 0xF124 "ABCD" 0xF128 0xF12C (char*) x 0xF130 &y (char**) z 0xF134???? Means: 0xF120 0xF124 "ABCD" 0xF128 0xF12C 0xF130 0xF124 0xF134???? 6 / 39
Casting Pointers Question What does this do? 1 # include <stdio.h> 2 int main () { 3 int x = 0 x00616263 ; 4 char *y = ( char *)&x; 5 printf ("%s", y); 6 return 0; 7 } What about the opposite: Casting a char * to an int * 7 / 39
Worksheet: Pointers Question (2) Fix this program by changing the function to use a pointer. 1 # include <stdio.h> 2 void lie ( int age ) { 3 printf (" You are %d years old \n", age ); 4 age += 1; 5 printf (" You are %d years old \n", age ); 6 } 7 8 int main () { 9 int age = 18; 10 lie ( age ); 11 printf (" But your age is still %d\n", age ); 12 return 0; 13 } 8 / 39
Question (3) Write a function zipmul that returns the product of the integers comprising the array that is passed to it. Call that function from main with an array of your choosing. Compile, run, and test your program. Note: This is implied from now on. Always test your code by calling it from main with appropriate inputs. 9 / 39
Question (4) Write a function mapdouble (modify the previous function) that also doubles each element of an integer array that is passed to it. 10 / 39
Question (5) Suppose we add an integer argument to the last function mapdouble(int* xs, int y) and perform the operation y = 2*y; in the function. Question (6) For the above function: (a) Do the array elements change value inside the function? (b) Does the integer y change value inside the function? (c) Does changing y s value also change the value of the integer that was passed as an argument by the calling function (main)? (d) Do the array element values remain changed after the function returns? 11 / 39
Question (7) Sketch a view of memory immediately before and after a function call that takes as parameters (a) an array of integers, and (b) a single integer. 12 / 39
Dynamic Memory Allocation Key points. 1. Local variables are allocated on the stack, in the function s stack frame. The stack is FILO: Easy access to most recently called functions. Stack frame is de-allocated after function returns. 2. Dynamically allocated variables are put on the heap. Remains allocated even after the allocating function returns 3. Global variables live in the program data segment String literals live in the read-only portion 13 / 39
Worksheet: Pointers Question (1.5) Back to the last part of Question 1... 1 char * result [2]; 2 x = result [0]; 3 // some hidden code 4 result [0] = " read only "; 5 y = x [0]; 14 / 39
Worksheet: malloc and strings Question (1) For the following pieces of code determine: 1. How much space is allocated expressed as a function of sizeof(). 2. Where the space is allocated (i.e. stack, heap, global,... ). 3. When the space is deallocated. 15 / 39
Example (1.1) The following program 1 int main (){ 2 int i; 3 } allocates sizeof(int) space on the stack frame for main which gets de-allocated when the program terminates. 16 / 39
Question (1.2) 1 int fun (){ 2 float i; 3 } 4 int main () { 5 fun (); 6 } 17 / 39
Question (1.3) 1 int fun ( char i){ 2 } 3 4 int main () { 5 fun ('a'); 6 } 18 / 39
Question (1.4) 1 int main () { 2 char i [10] = " hello "; 3 } 19 / 39
Question (1.5) 1 int main () { 2 char *i; 3 } 20 / 39
Question (1.6) 1 int main () { 2 int *i; 3 } 21 / 39
Question (1.7) 1 int main () { 2 char *i = " hello "; 3 } 22 / 39
Question (1.8) 1 int fun ( int *i) { 2 } 3 4 int main () { 5 int i [5] = {4, 5, 2, 5, 1}; 6 fun (i); 7 } 23 / 39
Question (1.9) 1 int main () { 2 int *i; 3 i = malloc ( sizeof ( int )); 4 } 24 / 39
Question (1.10) 1 void fun ( int **i) { 2 *i = malloc ( sizeof ( int ) *7) ; 3 } 4 5 int main () { 6 int *i; 7 fun (&i); 8 free (i); 9 } 25 / 39
Question (2) Write a program that declares 3 strings: first as "Monday" on the stack frame for main. second as the string literal "Tuesday". third as "Wednesday" on the heap. Save pointers for second and third in stack frame for main. 26 / 39
Question (3) Write statements to shorten the strings to their abbreviations (e.g. "Monday" to "Mon"). Which string cannot be changed in place? Why not? Question (4) Draw the memory model for your program. 27 / 39
Question (5) Add to your program so that it declares an array string_list of 3 pointers to first, second, and third. You now have an array of strings. Where is the memory allocated for this array? 28 / 39
Notice much of the allocation has happened in the function main. Question (6) What would happen if you changed main to be another function func and then returned from it? Which parts of your structure would remain allocated? Write a new function build month list that allocates, initializes and returns an array of 3 strings with the values "January", "February", and "March". All the strings should be mutable. 29 / 39
Command Line Arguments./mycalc add 5 4 3 2 1 Key points. 1. A program can receive input in many ways: command-line arguments are one of them. 2. Can use strtol function to parse strings containing integers 30 / 39
Worksheet: Command-line Arguments Question (1a) Suppose you have a program named prog.c, what is the instruction you would type on the command line, to compile this program and create an executable named prog? 31 / 39
Question (1b) You now have an executable named prog. Assuming it is in your current working directory, give the command to run that executable with the command-line arguments -k 3 myfile. 32 / 39
Question (1c) Assume that the executable is in your parent directory. Give the command to run the executable without any command-line arguments. 33 / 39
Question (1d) Assume the executable is your current working directory. Give the command to run the executable where the resulting output is redirected to a file named test1.out. 34 / 39
Question (1e) When you run the program, it interacts with the user expecting the user to type input. Give the command to run the program and redirect the input so that the executable instead reads from the file somefile.txt. 35 / 39
Question (1f) Run the executable prog with the command-line arguments -k 3 myfile, reading input from standard input redirected from somefile.txt and redirecting the output to test1.out. 36 / 39
Question (2) Add to the following code so that it prints the first two command line arguments. 1 # include <stdio.h> 2 int main ( int argc, char ** argv ) { 3 printf ("We have %d command - line arguments.\n", 4 argc - 1); 5 6 return 0; 7 } Question (3) Compile your program into an executable named args_practice. 37 / 39
Question (4) Run your program with two command-line arguments: 1. your name, 2. your enthusiasm (between 0 and 5) for hockey. Run it with no command-line arguments or only one. What happens? 38 / 39
Question (5) Change your program so that it takes your enthusiasm number (the second argument) and prints GO LEAFS GO GO SENS GO that many times. Did you get an error when you ran the program? (Remember that an individual command-line argument is a string (an array of char), so you need to use strtol to convert this argument into an integer.) 39 / 39