Skip to content

Latest commit

 

History

History
386 lines (267 loc) · 11.6 KB

File metadata and controls

386 lines (267 loc) · 11.6 KB

Homework 0

Watch the videos and write up your answers to the following questions

Important!

The virtual machine-in-your-browser and the videos you need for HW0 are here:

http://cs-education.github.io/sys/

Questions? Comments? Use Piazza: https://piazza.com/illinois/fall2019/cs241

The in-browser virtual machine runs entirely in Javascript and is fastest in Chrome. Note the VM and any code you write is reset when you reload the page, so copy your code to a separate document. The post-video challenges are not part of homework 0 but you learn the most by doing rather than just passively watching - so we suggest you have some fun with each end-of-video challenge.

HW0 questions are below. Please use this document to write the answers. This will be hand graded.

Chapter 1

In which our intrepid hero battles standard out, standard error, file descriptors and writing to files

  1. Hello, World! (system call style) Write a program that uses write() to print out “Hi! My name is <Your Name>”.
// Your code here
int main() {  
    write(1,"Hi! My name is <Your Name>", 26);  
	return 0;  
}  
  1. Hello, Standard Error Stream! Write a function to print out a triangle of height n to standard error. Your function should have the signature void write_triangle(int n) and should use write(). The triangle should look like this, for n = 3:
*
**
***
// Your code here
void write_triangle(int n){  
	int i,j;  
	for(i = 0; i < n; i++){  
		for(j = 0; j <= i; j++){  
	        write(2, "*",1);  
	        }  
	write(2,"\n",1);  
	}  
}  
int main() {  
	write_triangle(3);  
	return 0;  
}  
  1. Writing to files Take your program from “Hello, World!” modify it write to a file called hello_world.txt. Make sure to to use correct flags and a correct mode for open() (man 2 open is your friend).
// Your code here
int main() {  
	mode_t mode = S_IRUSR |S_IWUSR;  
	int file_ = open("hello_world.txt",O_CREAT|O_TRUNC| O_RDWR, mode);  
	write(file_, "Hi! My name is <Your Name>", 26);  
	return 0;     
}  
  1. Not everything is a system call Take your program from “Writing to files” and replace write() with printf(). Make sure to print to the file instead of standard out!
// Your code here
int main() {  
	close(1);  
	mode_t mode = S_IRUSR |S_IWUSR;  
	int file_ = open("hello_world.txt",O_CREAT|O_TRUNC| O_RDWR, mode);  
	printf("Hi! My name is <Your Name>\n");  
	close(file_);  
	return 0;     
}
  1. What are some differences between write() and printf()?
// Your code here
The write() is a system called implemented by the operating system, and run in kernel mode. However, printf() is a function call in library which are implemented in user mode and printf() will eventually invoke write().

Chapter 2

Sizing up C types and their limits, int and char arrays, and incrementing pointers

  1. How many bits are there in a byte?
// Your answer here
At least 8 bits
  1. How many bytes are there in a char?
// Your answer here
1 byte.
  1. How many bytes the following are on your machine?
  • int: 4
  • double: 8
  • float: 4
  • long: 4
  • long long: 8
  1. On a machine with 8 byte integers, the declaration for the variable data is int data[8]. If the address of data is 0x7fbd9d40, then what is the address of data+2?
// Your answer here
0x7fbd9d50
  1. What is data[3] equivalent to in C? Hint: what does C convert data[3] to before dereferencing the address? Remember, the type of a string constant abc is an array.
// Your answer here
 data+3 or 3[data]
  1. Why does this segfault?
char *ptr = "hello";
*ptr = 'J';
Hellois a read only constant literal string which cannot be changed
  1. What does sizeof("Hello\0World") return?
// Your answer here
12
  1. What does strlen("Hello\0World") return?
// Your answer here
5
  1. Give an example of X such that sizeof(X) is 3.
// Your code here
sizeof("aa")
  1. Give an example of Y such that sizeof(Y) might be 4 or 8 depending on the machine.
// Your code here
int Y
sizeof(Y)

Chapter 3

Program arguments, environment variables, and working with character arrays (strings)

  1. What are two ways to find the length of argv? Print the argc or using for loop to count the number of argv

  2. What does argv[0] represent? Program name

  3. Where are the pointers to environment variables stored (on the stack, the heap, somewhere else)? They are located somewhere else and we can use extern to use them

  4. On a machine where pointers are 8 bytes, and with the following code:

    char *ptr = "Hello";
    char array[] = "Hello";

    What are the values of sizeof(ptr) and sizeof(array)? Why?

// Your answer here
	sizeof(ptr) == 8 and sizeof(array) ==6 because sizeof(ptr) actually the number of bytes to hold the char pointer which is 8 bytes and sizeof(array) is the size of total length to hold the array.
  1. What data structure manages the lifetime of automatic variables? Stack

Chapter 4

Heap and stack memory, and working with structs

  1. If I want to use data after the lifetime of the function it was created in ends, where should I put it? How do I put it there? Using keyword static in front of a variable or using malloc to allocate some heap memory are two feasible solutions If you want to use data after the lifetime of the function it was created in ends.
  2. What are the differences between heap and stack memory? Stack memory will free automatically after the function return, but heap memory will not free automatically and it will last until the end of program process or we manually free the memory.
  3. Are there other kinds of memory in a process? Kernel memory, Text segment, Data segment
  4. Fill in the blank: “In a good C program, for every malloc, there is a ___”. "In a good C program, for every malloc, there is a free".
  5. What is one reason malloc can fail? Heap memory are full and cannot allocate new space.
  6. What are some differences between time() and ctime()? Time() is a system call which will return a time_t pointer, and ctime() is a function call in time library which will return a readable format of current time.
  7. What is wrong with this code snippet?
free(ptr);
free(ptr);
Double free the same memory
  1. What is wrong with this code snippet?
free(ptr);
printf("%s\n", ptr);
Access some memory which already do not exist, and ptr becomes a dangling pointer
  1. How can one avoid the previous two mistakes? Only free memory once and after free the memory, assign the pointer to NULL

  2. Use the following space for the next four questions

// 10

// 12

// 13

	struct Person {  
	    char* name;  
	    int age;  
	    struct Person** list;  
	};  
	typedef struct Person Person;  
	  
	Person* create(const char* name, const int age){  
	    Person* p = (Person*)malloc(sizeof(Person));  
	    p->name = strdup(name);  
	    p->age = age;  
	    p->list = malloc(sizeof(Person*) * 10);  
	    int i;  
	    for (i=0; i<10; i++) {  
	        p->list[i] = NULL;  
	    }  
	    return p;  
	}  
	void destory(Person* p){  
	    free(p->list); p->list = NULL;  
	    free(p->name); p->name = NULL;  
	    free(p); p = NULL;  
	}  
	  
	int main() {  
	    Person* as = create("Agent Smith", 128);  
	    Person* sm = create("Sonny Moore", 256);  
	    as->list[0] = sm;  
	    sm->list[0] = as;  
	    destory(as);  
	    destory(sm);  
	    return 0;  
	}
  • Create a struct that represents a Person. Then make a typedef, so that struct Person can be replaced with a single word. A person should contain the following information: their name (a string), their age (an integer), and a list of their friends (stored as a pointer to an array of pointers to Persons).

  • Now, make two persons on the heap, “Agent Smith” and “Sonny Moore”, who are 128 and 256 years old respectively and are friends with each other. Create functions to create and destroy a Person (Person’s and their names should live on the heap).

  • create() should take a name and age. The name should be copied onto the heap. Use malloc to reserve sufficient memory for everyone having up to ten friends. Be sure initialize all fields (why?).

  • destroy() should free up not only the memory of the person struct, but also free all of its attributes that are stored on the heap. Destroying one person should not destroy any others.

Chapter 5

Text input and output and parsing using getchar, gets, and getline.

  1. What functions can be used for getting characters from stdin and writing them to stdout? getchar() putchar()

  2. Name one issue with gets(). might cause buffer overflow

  3. Write code that parses the string “Hello 5 World” and initializes 3 variables to “Hello”, 5, and “World”.

// Your code here
	int main() {  
	    char* str = "Hello 5 World";  
	    char one[20];  
	    int two;  
	    char three[20];  
	    int result = sscanf(str, "%s %d %s", one, &two, three);  
	    printf("Result: %d, first: %s, second: %d, third: %s\n", result, one, two, three);  
	    return 0;  
	} 
  1. What does one need to define before including getline()? Define _GNU_SOURCE buffer and capacity

  2. Write a C program to print out the content of a file line-by-line using getline().

// Your code here
	int main() {  
	    char* buffer = NULL;  
	    size_t num = 0;  
	      
	    ssize_t result = getline(&buffer, &num, stdin);  
	      
	    free(buffer);  
	    return result;  
	      
	}  

C Development

These are general tips for compiling and developing using a compiler and git. Some web searches will be useful here

  1. What compiler flag is used to generate a debug build? make debug

  2. You fix a problem in the Makefile and type make again. Explain why this may be insufficient to generate a new build. The reason is that they are two kinds of modes so we will output a build with debug mode instead of a new build.

  3. Are tabs or spaces used to indent the commands after the rule in a Makefile? using tabs.

  4. What does git commit do? What’s a sha in the context of git? git commit records the changes to the repository and sha is a unique id to keep track of records.

  5. What does git log show you? git log shows all the history commit informations.

  6. What does git status tell you and how would the contents of .gitignore change its output? git status will show paths that are different between the index file and the current HEAD commit and it simply will ignore the contents in .gitignore

  7. What does git push do? Why is it not just sufficient to commit with git commit -m ’fixed all bugs’ ? git push will update all related objects in remote repository, because git commit only update the records and have no effects to change the remote repo.

  8. What does a non-fast-forward error git push reject mean? What is the most common way of dealing with this? It means another person has pushed to the same branch and to deal with this we need to git pull.

Optional: Just for fun

  • Convert your a song lyrics into System Programming and C code covered in this wiki book and share on Piazza.

  • Find, in your opinion, the best and worst C code on the web and post the link to Piazza.

  • Write a short C program with a deliberate subtle C bug and post it on Piazza to see if others can spot your bug.

  • Do you have any cool/disastrous system programming bugs you’ve heard about? Feel free to share with your peers and the course staff on piazza.