This was an exam on Canvas. Several questions used question banks, so this is an example exam.
Unless otherwise stated, please assume that you are working on a little endian machine with four-byte pointers.
#include <stdio.h> struct pebbles { char x1; short x2; int x3; double x4; void *v; }; int main() { int i; i = sizeof(struct pebbles); printf("%d\n", i); return 0; }[______________]
#include <stdio.h> struct wilma { int x1; char x2; }; int main() { int i; i = sizeof(struct wilma); printf("%d\n", i); return 0; }[______________]
#include <stdio.h> struct fred { char x1; int x2; }; int main() { int i; i = sizeof(struct fred); printf("%d\n", i); return 0; }[______________]
char *strcpy(char *dst, const char *src); char *strcat(char *dst, const char *src); void *memcpy(void *dst, const void *src, size_t n);Behold the following program in C:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { char *x, *s, *t;; int i; s = (char *) malloc(sizeof(char) * 50); t = (char *) malloc(sizeof(char) * 50); // 012345678901234567890123 strcpy(s, "KYFGUNDIWZPERCOVSTJQALXM"); strcpy(t, "ABCDEFG"); memcpy(t+3, s, 2); printf("1-%s\n", t); strcpy(t, "HIJKLMN"); strcpy(t+3, s+20); printf("2-%s\n", t); // 012345678901234567890123 strcpy(s, "KYFGUNDIWZPERCOVSTJQALXM"); for (x = s; x - s < 23; x += 5) *x = '\0'; printf("3-%s\n", s); printf("4-%s\n", s+7); printf("5-%s\n", s+14); printf("6-%s\n", s+21); strcat(s+1, "OPQR"); printf("7-%s\n", s+1); return 0; }Please answer the following questions:
char *strcpy(char *dst, const char *src); void *memcpy(void *dst, const void *src, size_t n);The ASCII value of the character 'A' is 0x41.
Behold the following program in C:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { unsigned int *r, *x, num; unsigned char *s; char *t; r = (unsigned int *) malloc(sizeof(unsigned int) * 4); s = (unsigned char *) r; num = 0x374a9a7c; for (x = r; x < r+4; x++) { *x = num; num += 0x11111111; } t = (char *) (r+1); strcpy(t, "BEAD"); printf("0x%08x\n", *r); /* Line 1 */ printf("0x%08x\n", *(r+1)); /* Line 2 */ printf("0x%08x\n", *(r+2)); /* Line 3 */ printf("0x%08x\n", *(r+3)); /* Line 4 */ printf("0x%02x\n", *s); /* Line 5 */ printf("0x%02x\n", *(s+5)); /* Line 6 */ printf("0x%02x\n", *(s+10)); /* Line 7 */ printf("0x%02x\n", *(s+15)); /* Line 8 */ memcpy(&num, s+10, 4); printf("0x%x\n", num); /* Line 9 */ s += 20; x = (unsigned int *) s; printf("%ld\n", x-r); /* Line 10 */ return 0; }Please answer the following questions:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> struct fred { int i; int *ip; int **ipp; struct fred *fp; }; void proc_a(struct fred *f) { printf("0x%02x\n", f->i & 0xff); /* Line 1 */ printf("0x%02x\n", ((unsigned int) f->ip) & 0xff); /* Line 2 */ printf("0x%02x\n", *(f->ip) & 0xff); /* Line 3 */ printf("0x%02x\n", **(f->ipp) & 0xff); /* Line 4 */ printf("0x%02x\n", f->fp->i & 0xff); /* Line 5 */ printf("0x%02x\n", f->fp->fp->i & 0xff); /* Line 6 */ printf("0x%02x\n", f[1].i & 0xff); /* Line 7 */ printf("0x%02x\n", f[2].i & 0xff); /* Line 8 */ printf("0x%02x\n", f[3].fp->i & 0xff); /* Line 9 */ } |
When we run proc_a, the value of f is: 0x7685c1e8.
The contents of memory are as listed below:
Address Value ---------- ---------- 0x7685c1e8 0x7685c20c 0x7685c1ec 0x7685c21c 0x7685c1f0 0x7685c208 0x7685c1f4 0x7685c224 0x7685c1f8 0x7685c1f8 0x7685c1fc 0x7685c220 0x7685c200 0x7685c1f4 0x7685c204 0x7685c228 0x7685c208 0x7685c230 0x7685c20c 0x7685c1f0 0x7685c210 0x7685c224 0x7685c214 0x7685c1f4 0x7685c218 0x7685c230 0x7685c21c 0x7685c1ec 0x7685c220 0x7685c1e8 0x7685c224 0x7685c1e8 0x7685c228 0x7685c220 0x7685c22c 0x7685c234 0x7685c230 0x7685c214 0x7685c234 0x7685c20cPlease answer the following questions:
UNIX> ls -l total 16 drwxr-xr-x 2 plank staff 64 Feb 27 23:41 dir1 -rw-r--r-- 1 plank staff 638 Feb 27 23:34 f1.txt -rw-r--r-- 1 plank staff 746 Feb 27 23:35 f2.txt UNIX> ln f1.txt dir1/f3.txt UNIX> echo fred >> f1.txt UNIX>These actions have changed a few things on my disk. Please tell me, to the best of your knowledge in what I have taught you, exactly what has changed on the disk.
For example:
UNIX> ls -la total 32 drwxr-xr-x 6 plank staff 192 Feb 27 20:45 . drwxr-xr-x 29 plank staff 928 Feb 27 20:45 .. -rw-r--r-- 1 plank staff 1570 Feb 27 20:45 aaa.txt drwxr-xr-x 2 plank staff 64 Feb 27 20:53 dir1 -rw-r--r-- 1 plank staff 1570 Feb 27 20:45 f1.txt -rw-r--r-- 1 plank staff 1596 Feb 27 20:45 f2.txt -rw-r--r-- 1 plank staff 1544 Feb 27 20:45 f3.txt UNIX> ./a.out f2.txt aaa.txt f1.txt f3.txt .. . dir1 UNIX>Here are some useful prototypes and the like:
extern JRB make_jrb(); extern JRB jrb_insert_str(JRB tree, char *key, Jval val); extern JRB jrb_insert_int(JRB tree, int ikey, Jval val); extern JRB jrb_insert_dbl(JRB tree, double dkey, Jval val); extern JRB jrb_insert_gen(JRB tree, Jval key, Jval val, int (*func)(Jval,Jval)); extern JRB jrb_find_str(JRB root, char *key); extern JRB jrb_find_int(JRB root, int ikey); extern JRB jrb_find_dbl(JRB root, double dkey); extern JRB jrb_find_gen(JRB root, Jval, int (*func)(Jval, Jval)); extern void jrb_delete_node(JRB node); extern void jrb_free_tree(JRB root); #define jrb_traverse(ptr, lst) \ for(ptr = lst->flink; ptr != lst; ptr = ptr->flink)) extern Dllist new_dllist(); extern dll_append(Dllist, Jval); extern dll_prepend(Dllist, Jval); extern dll_insert_b(Dllist, Jval); extern dll_insert_a(Dllist, Jval); extern dll_delete_node(Dllist); extern free_dllist(Dllist); #define dll_traverse(ptr, lst) \ for(ptr = lst->flink; ptr != lst; ptr = ptr->flink)) char *strchr(const char *s, int c); /* Return NULL if not found */ char *strstr(const char *s1, const char *s2); /* Return NULL if not found */ int lstat(const char *path, struct stat *buf); int stat(const char *path, struct stat *buf); DIR * opendir(const char *dirname); int closedir(DIR *dirp); struct dirent *readdir(DIR *dirp); /* The only thing you care about in a struct dirent is the field d_name which is a char * */ struct stat { dev_t st_dev; /* device inode resides on */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number or hard links to the file */ uid_t st_uid; /* user-id of owner */ gid_t st_gid; /* group-id of owner */ dev_t st_rdev; /* device type, for special file inode */ off_t st_size; /* file size, in bytes */ }; int chmod(const char *path, mode_t mode); mode_t umask(mode_t cmask); int system(const char *command); int open(const char *path, int oflag, ...); |
void *open_logfile(const char *filename); void write_logentry(void *logfile, void *logentry); void close_logfile(void *logfile); |
The second file is a quick implementation that your co-worker wrote to show you the desired behavior:
#include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include "logfile.h" typedef struct { int fd; } Logfile; void *open_logfile(const char *filename) { int fd; Logfile *l; fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd < 0) return NULL; l = (Logfile *) malloc(sizeof(Logfile)); l->fd = fd; return (void *) l; } void write_logentry(void *logfile, void *logentry) { Logfile *l; l = (Logfile *) logfile; write(l->fd, logentry, 16); } void close_logfile(void *logfile) { Logfile *l; l = (Logfile *) logfile; close(l->fd); free(l); } |
Your job is rewrite this implementation to make it efficient.
Here are prototypes of system/library calls that you may use. You may not use any others:
int open(const char *path, int oflag, [int mode]); int write(int fildes, const void *buf, size_t nbytes); int close(int fildes); void *malloc(int size); void free(void *ptr); void *memcpy(void *dest, const void *src, size_t nbytes); |
Please do not bother with #include statements. You don't have to do any additional error checking than the above procedures do.