Cmsc 216

¡Supera tus tareas y exámenes ahora con Quizwiz!

What does omitting the tag of an argument mean? ex. struct { int id_number; char last_name[10]; char first_name[10]; double salary; } emp1, emp2;

Declares two variables (emp1 and emp2) You cannot define any other variables of this type Omitting tag means you create a unique type for the variables listed -Prevents use of those structs as function arguments

What is the output of the following? char str[] = "ice cream"; printf("\"%s\": %d chars\n", str, strlen(str));

"ice cream": 9 chars

What is a process?

A Process is a running program (one or more threads of control), along with all the data associated with it (an address space)

how is dup2 declared?

int dup2(int old_fd, int new_fd); int fd1 = open(filename, O_RDONLY); dup2(fd1, STDIN_FILENO);

Valid/Invallid? int i = 4, j = 5; const int *p = &i; int * const q = &j; p = &j; /* LINE 1: vaid/invalid */ *p += 5; /* LINE 2: vaid/invalid */ q = &i; /* LINE 3: vaid/invalid */ *q += 23; /* LINE 4: vaid/invalid */

int i = 4, j = 5; const int *p = &i; /* pointer to constant int */ int * const q = &j; /* constant pointer to int */ p = &j; /* OK */ *p += 5; /* ERROR */ q = &i; /* ERROR */ *q += 23; /* OK */

What do we use the -> operator for?

Given a pointer to a structure we can use the -> operator to reference the fields of a structure

Give an initialization equal to the following int a[]

int *a

Malloc vs Calloc Where are the included? What are the differences?

#include <stdlib.h> - void *malloc(size_t amount); • allocates amount bytes of memory (if available) from the heap and returns a pointer to the beginning of it • no initialization of the space!! - void *calloc(size_t count, size_t obj_size); • allocates count objects of size obj_size each (if memory is available), returns a pointer to beginning of it • initializes all the space to 0!! - both return NULL if the allocation fails

sum array in assembly

# sums x number of elements from an array irmovl $0, %eax # has the sum rdint %ebx # how many elements to add irmovl $0, %esi # iteration variable irmovl MyData, %edx # array start address rrmovl %esi, %ecx subl %ebx, %ecx je EndLoop Loop: mrmovl 0(%edx), %ecx # array element placed in register addl %ecx, %eax # adding value to accumulator irmovl $4, %edi # moving to next element addl %edi, %edx irmovl $1, %edi # increasing count addl %edi, %esi rrmovl %esi, %ecx #checking we are done subl %ebx, %ecx jne Loop EndLoop: wrint %eax irmovl $10, %esi wrch %esi halt .align 4 MyData: .long 10 .long 20 .long 30 .long 40 .long 50 .long 60

What the #define directive most commonly used for?

#define • Most commonly used for constants • By convention, we use all capital letters for our constants - makes it easier for humans to recognize them

Printf() format specifiers

#include <stdio.h> %c print the corresponding argument to printf as an unsigned char %d print as a decimal integer %u print as an unsigned integer %x print in hexadecimal (use %X for capital A-F) %f print in floating point format %e print in exponential form (e.g., 6.02300e3) %s print as a string (null-terminated character array) %% print a % (so %% prints as %)

What are the two types of scopes in C

- Block scope: a variable declared inside a block is visible only within the block (includes nested blocks inside that block) - File scope: an identifier declared outside of any block is visible everywhere in the file after the declaratio

what is a signal

- a signal is an asynchronous notification sent to a process

Define these system calls alarm pause

- alarm: arranges for a SIGALRM signal to be sent to the calling process x seconds later - pause: causes calling process to suspend until a signal is received • note: Don't mix sleep and pause

• To compile a program that uses a static library:

- suppose the program in main.c wants to use functions from the library libavl.a (which has the functions from avl.o and node.o) created above: gcc -o main main.o libavl.a

•what are Limits on compiler optimizations?

- the compiler has a limited understanding of the program

What are common errors of dynamic memory allocation?

-Dereferencing pointers to freed space (directly or indirectly) - Forgetting to check the return value from malloc() for NULL - Not initializing the memory malloc() returns - Not allocating enough space: Common errors • Dereferencing a random address (garbage pointer) int *p; *p = 42; • Dereferencing a NULL pointer int *p; p = NULL; *p = 23; • Dereferencing a dangling pointer int *p = malloc(...); free(p); ... *p = 27; Using freed memory List_node *ptr = malloc(sizeof(List_node)); ... free(ptr); ... ptr = ptr->next; /* Uh oh... */

/*Process Control*/

/*process control*/ getppid() = parent getpid() = child #define DEF = 0x666 int fd1 = open(".txt", DEF); /*066 Read and write only*/ close(fd1); /*basic process using pipes*/ pid_t child_pid; int pipe_fd[2]; pipe(pip_fd); fork(chiild_pid); if(child_pid){/*parent*/ close(fd[1]); read(pipe_fd[0], buff, BUFSIZ) close(pipe_fd[0]); wait(NULL); } else{ close(fd[0]); char *a [BUFFSIZ] = "Hello"; /*read(store in pipe or file, ReadFrom, size)*/ write(pip_fd[1], a, BUFFSIZ); close(fd[1]); } /*DUP2*/ /*STDIN points to that file*/ /*OPEN FILE*/ dup2(".txt", STD_IN); dup2(.txt, STD_OUT);

What are the two types of storage in C?

1. Automatic: the previous variable j has automatic storage, meaning it is no longer maintained after its function returns default for block-scoped variables 2. Static: variable exists throughout the entire life of the program

What are the 3 compilation stages and what do they do?

1. Preprocessor used to make sure the program parts see declarations they need (and other purposes too, e.g., macros) - directives begin with a # (pound sign) - do not end in a ; like C statements do 2. Translation - makes sure individual parts are consistent within themselves - creates an object (.o) file 3. Linking - joins one or more compiled object files together includes matching function call to callee across separate files and matching global variable use to where it's defined -Default a.out

What are 3 roles of an operating system?

1. Protect the computer from misuse 2. Provide an abstraction for using the hardware so that programs can be written for a variety of different hardware 3. Manage the resources to allow for reasonable use by all users and programs on a compute

What is the output? int main() { int idx; int a[3] = {10, 20, 30}; for (idx = 0; idx < 3; idx++) { printf("%d ", a[idx]); } printf("\n"); /* No size specified */ char b[] = {'A', 'B', 'C'}; for (idx = 0; idx < 3; idx++) { printf("%c ", b[idx]); } printf("\n"); /* Only one initializer value */ float c[4] = {1.5}; for (idx = 0; idx < 4; idx++) { printf("%f ", c[idx]); } printf("\n"); return 0; }

10 20 30 A B C 1.500000 0.000000 0.000000 0.000000

What is the output? int main() { int i = 4; int j = 6; int *p = &i; int *q = &j; int **r = &p; printf("%d\n", **r); *r = &j; printf("%d\n", *p); printf("%d\n", *q); return 0; }

4 6 6

What are the two types of libraries? .a ? .os ?

Archive(static) libraries (extension .a, for "archive") - linked into a program as part of the linking phase of compilation - require space in each executable that uses them - easy to use • Shared libraries (extension .so, for "shared object") - require only one copy for the entire system

/*MakeFiles*/

CC = gcc CFLAGS = -Wall course: course.o student.o $(CC) -o course course.o student.o course.o: course.c student.h $(CC) $(CFLAGS) -c course.c student.o: student.c student.h id.h $(CC) $(CFLAGS) -c student.c clean: rm *.o course

How do you deallocate memory in C?

Deallocating memory - void free(void *ptr); • returns the memory pointed to by ptr to the free pool in the heap • memory MUST have been previously allocated from the heap • does not change ptr (why not?), so you may want to set ptr to NULL after calling free() if you might accidentally use ptr again NOTE: • free(NULL); does nothing - it's perfectly OK to do

Write a makefile based on the following information. 1. Files associated with the system: a. course.c application driver b. student.c provides functions used by course.c c. student.h included by student.c and course.c d. id.h included by student.c 2. Main targets a. course we should be able to create an executable named "course" b. clean this will remove .o files and executables c. Any other targets you understand are necessary. 3. The compiler to use is gcc with the -Wall flag. 4. You may not use implicit rules.

CC = gcc CFLAGS = -Wall course: course.o student.o $(CC) -o course course.o student.o course.o: course.c student.h $(CC) $(CFLAGS) -c course.c student.o: student.c student.h id.h $(CC) $(CFLAGS) -c student.c clean: rm *.o course

Define the following: • Code motion • Loop unrolling • Dead code elimination

Code motion take out redeclarations in for-loop Loop unrolling - things can often be faster if a loop body is a bit bigger, because modern processors can perform several instructions (or at least parts of them) simultaneously Dead code elimination - if the compiler can infer that some code can never be executed, the code can be removed

Signals sources Via control characters at the keyboard SIGINT(terminate process) is what keyboard command ? s SIGTSTP (suspend process execution)? kill system call vs kill system command? software errors define: SIGPIPE SIGFPE SIGSEGV External events define SIGCHLD

Ctrl-C sends SIGINT (terminates process) Ctrl-Z sends SIGTSTP (suspend process execution) Unix kill command - kill -l lists all signals kills everything kill system call dosent have to kill everything kernel sends SIGPIPE when process writes to pipe that has been closed by the reader (by default process will be terminated) - division by zero (SIGFPE) - segmentation violation (SIGSEGV SIGCHLD - generated by child processes when they finished, and when stopped by SIGTSTP or SIGSTOP P

Their is a string type in C? True/False

False: There is no String type in C

Are the following equivalent why or why not char name[] = "Mary"; char *name = "Mary";

First declaration creates an arrayWhat you should be using if planning to change the name value • Second declares name as a pointer to a string literal

What is wrong with the following code? int *p = calloc(10, sizeof(int)); free(p + 3);

Freeing something that's not the beginning of a dynamically allocated block:

What does freeing the space do?

Freeing the space doesn't change the value of the pointer or the value of the space pointed at

What is the constant modifier? what is the difference between the following statments? const int * vs int const * ex. int i = 4, j = 5; const int *p = &i; int * const q = &j;

Indint i = 4, j = 5; const int *p = &i; /* pointer to constant int */ int * const q = &j; /* constant pointer to int */ p = &j; /* OK */ *p += 5; /* ERROR */ q = &i; /* ERROR */ *q += 23; /* OK */icates that a variable can't be changed, and enforced by compiler

outputs? char name[ARRSIZE]= "Jeff Jones"; cptr= &name[5]; printf("%s\n", cptr); printf("%c and %c\n", *(cptr + 3), *(cptr - 4));

Jones e and e f and s

What is Linkage and what are the 3 types?

Linkage: a property of an identifier that determines if multiple declarations of that identifier refer to the same object • Three types of linkage 1. none: all declarations of an identifier refer to different entities (i.e., one copy per declaration) 2. internal: all declarations of an identifier inside a given file refer to the same entity, but declarations across files refer to different entities (i.e., one copy per file) 3. external: all declarations of an identifier refer to the same entity (i.e., one copy per program)

What is the output? int main() { char mascot[] = "terps"; char city[13] = "College Park"; /* Why 13? */ char state[20] = "Maryland"; char zipCode[6] = {'2','0','7', '4', '2', '\0'}; int idx; printf("Mascot: %s\n", mascot); printf("City: %s\n", city); printf("Printing state character by character: "); for (idx = 0; idx < 8; idx++) { printf("%c", state[idx]); } printf("\n"); printf("Zipcode: %s\n", zipCode); return 0; }

Mascot: terps City: College Park Printing state character by character: Maryland Zipcode: 20742

Write the code to delete from a linked list. typedef struct node { int val; struct node *next; /* Notice use of tag */ } Node; int insert(Node **head, int new_value) { /*code here*/ } Node *current = *head, *prev = NULL, *new_item; while (current != NULL && current->val < new_value) { prev = current; current = current->next; }

NOTE: MALLOC WHEN ADDING! int insert(Node **head, int new_value) { Node *current = *head, *prev = NULL, *new_item; while (current != NULL && current->val < new_value) { prev = current; current = current->next; } new_item = malloc(sizeof(*new_item)); if (new_item == NULL) return 0; new_item->val = new_value; new_item->next = current; if (prev == NULL) *head = new_item; else prev->next = new_item; return 1; }

What are the issues in conducting measurments?

Number of runs: take the mean of the K fastest runs • Workload: does the complexity seem correct?

Define principal of locality, temporal and spatial

Principle of locality: - programs tend to reuse data and instructions near those they have used recently, or that were recently referenced themselves - temporal locality: recently referenced items are likely to be referenced again in the near future - spatial locality: items with nearby addresses tend to be referenced close together in time

Write the code to delete from a linked list. typedef struct node { int val; struct node *next; /* Notice use of tag */ } Node; int delete(Node **head, int value) { /*code here*/ }

REMEMBER POINTER TO POINTER TO HEAD NOTE: FREE WHEN DELETING FROM LINKED LIST int delete(Node **head, int value) { Node *prev = NULL, *current = *head; while (current != NULL && current->data != value) { prev = current; current = current->next; } if (current == NULL) return 0; /* not found */ if (prev != NULL) prev->next = current->next; else *head = current->next; /* deleted first item */ free(current); return 1; }

What is realloc?

Reallocation: If you need more space than you originally allocated, you could handle this yourself: void *realloc(void *p, size_t new_size); • checks current size of the block p points to - if original size >= new_size, can perform reallocation in place, and returns p - if original size < new_size, new block of size new_size is allocated • if allocation fails, returns NULL • otherwise, copies items from p over, free p, and returns pointer to new block

what is the output? int main() { int *p = NULL; *p = 200; printf("The value is %d\n", *p); return 0; }

Sef Fault

Give the output of the following int main(){ int *p; *p = 200; printf("The value is %d\n", *p); return 0; }

Seg Fault

Structure argument are passed by reference or value?

Structure arguments are passed by value

Give an example of a dangler pointer

int *p, *q; p = malloc(sizeof(int)); *p = 99; q = p; /*values of p and q and *p and *q*/ free(p); p = NULL; *q = 42;

True/False If a function modifies elements of an array parameter, the array passed in is always modified?

True

Structures Vs. Unions what are the differences?

Unions • Look much like structures • But all fields share the same memory space, so are only as large as largest field • Only one field valid at a time Structures • Like arrays, hold multiple items • Items need not be of the same type • Items referred to by field names, not numerical indices • Similar to a Java class with all public fields and no methods

What is the output? int main() { int x = 20; int *ptr = &x; printf("Value of x is: %d\n", x); printf("Size of integer: %ld\n", sizeof(x)); printf("Value of x via pointer is: %d\n", *ptr); printf("Size of pointer variable is: %ld\n", sizeof(ptr)); printf("Pointer value is: %p\n", ptr); return 0; }

Value of x is: 20 Size of integer: 4 Value of x via pointer is: 20 Size of pointer variable is: 8 Pointer value is: 0x7fff72b02c34

What is the output? void process(void *dataPtr, int type) { int a; double b; if (type == 1) { a = *((int *)dataPtr); printf("int value provided %d\n", a); } else if (type == 2) { b = *((float *)dataPtr); printf("float value provided %f\n", b); } else { printf("Invalid type provided\n"); } } int main() { int x = 200; float y = 4.4; int *xPtr; void *vPtr; /* You can assign any address to a void pointer */ vPtr = &y; /* assigning pointer to float */ vPtr = &x; /* assigning pointer to int */ /* We cannot dereference void ptr */ /* *vPtr = 100; */ *((int *)vPtr) = 400; printf("Value of x: %d\n", x); xPtr = (int *)vPtr; *xPtr = 600; printf("Value of x: %d\n", x); /* Void pointers allow us to pass any data */ process(&x, 1); process(&y, 2); return 0; }

Value of x: 400 Value of x: 600 int value provided 600 float value provided 4.400000

#include "file.h" What if file.h #includes another file? What if two header files #include the same third header file?

What if file.h #includes another file? - That's fine, preprocessor can handle it What if two header files #include the same third header file? Also okay, unless a program #includes both of the first two header files..

What is the program loader?

When you run a program the program loader finds and loads all shared libraries used by a program

Write a makefile rule that creates the target atom.o. The file atom.c includes the files atom.h. Do not use implicit rules or macros.

atom.o: atom.c atom.h gcc -c atom.c

What are all the data types and sizes in C(specifically linux.grace)

char 1 short 2 int 4 long 8 float 4 double 8 long double 12 Note that variables of type char are guaranteed to always be one byte.

/* I/O */

char buf[1025]; char *a; char *b; fscanf(stdin,"%s %s", a, b) fgets() /*reads line by line*/ char buf[1025]; int a, b; while(fgets(buf, 1024, stdin) != NULL) { if (sscanf(buf, "%d %d", &a, &b) == 2) { printf("%d %d\n", a, b); break; } }

Give example code using scanf() for strings

char first_name[MAX_LEN + 1]; printf("Enter your first name: "); scanf("%s", first_name); printf("Name provided is %s\n", first_name);

memcopy vs memove

copy whole blocks of memory void *memcpy(void *dst, void *src, size_t n); void *memmove(void *dst, void *src, size_t n); • Both copy n bytes from the memory starting at src to the memory starting at dst, and return the dst pointer • memcpy() cannot be used on overlapping arrays, though; but it's faster than memmove() • Both prototypes contained in string.h

What Pthreads function can be used by a thread to obtain the return value from another thread? And what is the equivalent function for a process, instead of a thread?

g. The Pthreads function is pthread join(), and the equivalent function for a process is waitpid().

Using gcc write the compilation line that will create an executable named myProg by compiling the program associated with a file called cloud.c

gcc cloud.c -o myProg

b. Floating point numbers are stored with:

i. the sign bit ii. the significand (or mantissa) iii. the exponent i. The sign bit is 1 for negative numbers, 0 for positive. ii. The mantissa is normalized to an "implied leading 1" or the mantissa is 1 <= M < 2. iii. The exponent is biased (always positive but meaning value-bias in order to get negative exponents)

How do you use scanf()?

int main() { char gender = 'N'; int age = -1; printf("Enter gender(M/F) and age: "); scanf("%c%d", &gender, &age); printf("Gender: %c, Age: %d\n", gender, age); return 0; } Note: %d, %x, %o - read a decimal, hex, or octal number into an int • %f read in a float • %lf read in a double • %c read in a char • %s read in a string (bounded by whitespace

An example with pipe()

int main() { int pipe_fd[2]; /* pipe */ char buf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ pid_t child_pid; /* Creating pipe */ if (pipe(pipe_fd) < 0) { err(EX_OSERR, "pipe error"); } if ((child_pid = fork()) < 0) { err(EX_OSERR, "fork error"); } if (child_pid) { /* parent code */ close(pipe_fd[1]); /* closing write end */ read(pipe_fd[0], buf, BUFSIZ); printf("Message from child: %s\n", buf); close(pipe_fd[0]); /* closing read end */ wait(NULL); /* reaping */ } else { /* child code */ char msg[] = "Hi there!"; close(pipe_fd[0]); /* closing read end */ write(pipe_fd[1], msg, sizeof(msg)); close(pipe_fd[1]); /* closing write end */ } return 0; }

How do you read from file into a string?

int readDataFromFile(char *fname, Exam allExams[]) { FILE *input; char buffer[MAX_LEN + 1]; int month, year, max_points, idx; input = fopen(fname, "r"); idx = 0; while (fgets(buffer, MAX_LEN + 1, input) != NULL) { sscanf(buffer, "%d %d %d", &month, &year, &max_points); initializeExam(month, year, max_points, &allExams[idx++]); } return idx; }

Read in this data from a file 220 20 50 call void initialize(int month, int yeat, int date) {}

int readDataFromFile(char *fname, Exam allExams[]) { FILE *input; char buffer[MAX_LEN + 1]; int month, year, max_points, idx; input = fopen(fname, "r"); idx = 0; while (fgets(buffer, MAX_LEN + 1, input) != NULL) { sscanf(buffer, "%d %d %d", &month, &year, &max_points); initializeExam(month, year, max_points, &allExams[idx++]); } return idx; }

/*Threading*/

pthread_mutex_init(&mutex, NULL);/*pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;*/ void* print2(void* n){ num = *((int *)(num)); int x = calloc(sieof(int), 1); x = n; return n; } main(){ int *x; pthread_t t1; p_thread_create(&t1, NULL, print, x); void *intToPrint; p_thread_join(t1, &intToPrint);//void** int intToPrint2 = *((int *)(intToPrint)); printf("%d\n", inToPrint);

#assembly

pushl %edx call addone pushl %edx addone: pushl %ebp rrmovl %esp, %ebp #WAYS TO USE LOCAL VARIABLES pushl %eax popl %eax #must pre allocate space to use ebp irmovl $4, %ecxm subl %ecx, %esp rmmovl %ebx, -4(%ebp) rmmovl %ebx, -12(%esp) #END OF LOCAL VARIABLE EXAMPLES popl %ebp rrmovl %ebp, %esp

How to declare and lock semaphore?

sem_init(&mutex, 0, 1); sem_wait(&mutex); sem_post(&mutex);

Name all of the string library functions discussed in class as defined in #include <string.h>

size_t strlen(const char *str); int strcmp(const char *s1, const char *s2); strcpy(char *dest, const char *src); - copies the string in src to dest - it is up to the programmer to ensure that dest is an array with enough characters to hold the string

/*Strings*/

size_t strlen(const char *str); int strcmp(const char *s1, const char *s2); strcpy(char *dest, const char *src);

Compilers can be asked to "optimize" your code how?

the gcc -O flag (and -ON) enables the optimizer, which makes modifications to the compiled program if possible

Eliminating race condition

void *print_point(void *arg) { Point p = * (Point *) arg; free(arg); printf("(%d, %d)\n", p.x, p.y); return NULL; } int main() { pthread_t tids[NUM_THREADS]; int i; Point *pt_ptr; for (i = 0; i < NUM_THREADS; i++) { pt_ptr = malloc(sizeof(*pt_ptr)); pt_ptr->x = i; pt_ptr->y = 3 * i + 2; pthread_create(&tids[i], NULL, print_point, pt_ptr); } for (i = 0; i < NUM_THREADS; i++) pthread_join(tids[i], NULL); return 0; }

(13 pts) Implement the function getBits that has the prototype below. The function initializes the bits array with the 0's and 1's associated with the value parameter. For example, calling the function with the value 0xabcd will initialize the array as follows: 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1. You can assume that an unsigned short has 2 bytes. For this problem you can use only 1 for loop. void getBits(int bits[], unsigned short value) {}

void getBits(int bits[], unsigned short value) { int totalBits = 16, idx; for (idx = totalBits - 1; idx >=0; idx--) { bits[idx] = value & 0x1; value = value >> 1; } }

Which if any of these work when passing a pointer to a struct to a function? void increase_x(Pixel *p, int delta) { p->y += delta; (*p).y += delta; *p.y += delta; }

void increase_x_and_y(Pixel *p, int delta) { p->x += delta; /*OK*/ (*p).y += delta; /*OK*/ /* *p.y += delta; WRONG */ }

typedef struct { int month; int year; } Date; typedef struct { Date date; int max_points; } Exam;

void initializeExam(int month, int year, int max_points, Exam *exam) { exam->date.month = month; exam->date.year = year; exam->max_points = max_points; }

What is wrong with the following code? int i, *p; p = &i; free(p);

• Attempting to free non-heap memory:

why do we need to close both ends of a pipe?

• Because of the blocking I/O, we need to close ends of the pipe that we're not using, both immediately after the fork and once we're finished reading/writing

How do you load libraries: during linking? during execution?

• During Linking - Explicitly on the compilation line - -l (and -L) on the compilation line • During Execution - Loaded into an application at program startup by using the environment variable LD_LIBRARY_PATH to find the library file it needs

SIGKILL and SIGSTOP cannot be ignored true or false?

• SIGKILL and SIGSTOP are signals that cannot be caught or ignored

What happens when you compile a program in C?

• Source files (*.c) compiled into object files (*.o) - Source file is first preprocessed - Preprocessed file is then compiled to assembly - Assembler converts assembly code to object code Object files are converted into an executable -Done by linker

• The UNIX utility nm does what?

• The UNIX utility nm lists the symbols (functions and other names) in a library

What do we use to detect memory leeks?

• valgrind --tool=memcheck a.out


Conjuntos de estudio relacionados

Chapter 5, Cardiovascular System Multiple Choice

View Set

GVLTEC IST 226 - Chapter Questions 9

View Set

chapter 16: the reformation in europe

View Set

Nature of Light: Subtractive and Additive Color Mixing Terms

View Set

ΒΙΟΛΟΓΙΑ ΓΕΝΙΚΗΣ Β ΛΥΚΕΙΟΥ

View Set