CSE 333 Midterm Exam Sample Solution 7/28/14

Similar documents
CSE 374 Final Exam 3/15/17. Name UW ID#

CSE 374 Final Exam 3/15/17 Sample Solution. Question 1. (8 points) Suppose we have the following two statements in a C program:

CSE 333 Midterm Exam July 24, Name UW ID#

CSCI-1200 Data Structures Spring 2016 Lecture 6 Pointers & Dynamic Memory

Debugging (Part 2) 1

Key C Topics: Tutorial Pointers, Dynamic Memory allocation, Valgrind and Makefile CS370

Memory Allocation in C C Programming and Software Tools. N.C. State Department of Computer Science

CSE 333 Midterm Exam July 24, 2017 Sample Solution

Princeton University Computer Science 217: Introduction to Programming Systems. Data Structures

CSE au Midterm Exam Nov. 2, 2018 Sample Solution

The assignment requires solving a matrix access problem using only pointers to access the array elements, and introduces the use of struct data types.

A Capacity: 10 Usage: 4 Data:

TI2725-C, C programming lab, course

Both parts center on the concept of a "mesa", and make use of the following data type:

CSE 333 Midterm Exam 5/9/14 Sample Solution

CSE 333 Midterm Exam Sample Solution 5/10/13

CSE 333 Midterm Exam Sample Solution 7/29/13

Use Dynamic Analysis Tools on Linux

CSE 333 Midterm Exam 2/14/14

CSE 333 Midterm Exam 7/29/13

Praktische Aspekte der Informatik

DEBUGGING: DYNAMIC PROGRAM ANALYSIS

CSE 333 Midterm Exam 7/27/15 Sample Solution

CSCI-1200 Data Structures Fall 2015 Lecture 6 Pointers & Dynamic Memory

Memory Analysis tools

CSCI-243 Exam 2 Review February 22, 2015 Presented by the RIT Computer Science Community

CSE 333 Midterm Exam 5/10/13

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

ECE551 Midterm Version 1

Kurt Schmidt. October 30, 2018

CSCI-1200 Data Structures Spring 2013 Lecture 7 Templated Classes & Vector Implementation

Intermediate Programming, Spring 2017*

CS61, Fall 2012 Section 2 Notes

ECE551 Midterm Version 2

CS 261 Fall C Introduction. Variables, Memory Model, Pointers, and Debugging. Mike Lam, Professor

ECE 551D Spring 2018 Midterm Exam

Common Misunderstandings from Exam 1 Material

CSE 333 Midterm Exam 7/22/12

Signature: ECE 551 Midterm Exam

CS 103 Lab The Files are *In* the Computer

ECE264 Spring 2014 Exam 2, March 11, 2014

ECE551 Midterm. There are 7 questions, with the point values as shown below. You have 75 minutes with a total of 75 points. Pace yourself accordingly.

CSE 333 Midterm Exam Nov. 3, 2017 Sample Solution

Scientific Programming in C IV. Pointers

Pointers and Memory Management

Projet 0 - Correc,on. Structures de données et algorithmes

Midterm Exam Nov 8th, COMS W3157 Advanced Programming Columbia University Fall Instructor: Jae Woo Lee.

CS 137 Part 5. Pointers, Arrays, Malloc, Variable Sized Arrays, Vectors. October 25th, 2017

CSE 333 Midterm Exam 7/25/16 Sample Solution. Question 1. (10 points) Preprocessor. Suppose we have the following two files:

C Introduction. Comparison w/ Java, Memory Model, and Pointers

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

CSE 333 Midterm Exam Cinco de Mayo, 2017 (May 5) Name UW ID#

Linked data structures. EECS 211 Winter 2019

CSE 333 Midterm Exam 2/12/16. Name UW ID#

CA341 - Comparative Programming Languages

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

COSC Software Engineering. Lecture 16: Managing Memory Managers

Intermediate Programming, Spring 2017*

ECE264 Fall 2013 Exam 3, November 20, 2013

CSE 374 Final Exam Sample Solution 3/17/11

CSE 333 Midterm Exam 7/25/16. Name UW ID#

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

Memory Management. CS449 Fall 2017

CSE 333 Autumn 2013 Midterm

Tutorial 1: Introduction to C Computer Architecture and Systems Programming ( )

advanced data types (2) typedef. today advanced data types (3) enum. mon 23 sep 2002 defining your own types using typedef

EE355 Lab 5 - The Files Are *In* the Computer

CSE351 Winter 2016, Final Examination March 16, 2016

Memory Organization. The machine code and data associated with it are in the code segment

Dynamic memory. EECS 211 Winter 2019

Arrays and Memory Management

ECE264 Fall 2013 Exam 2, October 24, 2013

C PROGRAMMING Lecture 5. 1st semester

CSE 333 Final Exam June 6, 2017 Sample Solution

The Valgrind Memory Checker. (i.e., Your best friend.)

Memory. What is memory? How is memory organized? Storage for variables, data, code etc. Text (Code) Data (Constants) BSS (Global and static variables)

unsigned char memory[] STACK ¼ 0x xC of address space globals function KERNEL code local variables

CSE 374 Final Exam Sample Solution 3/15/12

ECE 551D Spring 2018 Midterm Exam

(13-2) Dynamic Data Structures I H&K Chapter 13. Instructor - Andrew S. O Fallon CptS 121 (November 17, 2017) Washington State University

ECE264 Spring 2013 Final Exam, April 30, 2013

Creating a String Data Type in C

Warmup January 9th, What is the value of the following C expression? 8*9 % 10/ 2

Memory (Stack and Heap)

Deep C. Multifile projects Getting it running Data types Typecasting Memory management Pointers. CS-343 Operating Systems

Lecture 14 Notes. Brent Edmunds

CS C Primer. Tyler Szepesi. January 16, 2013

CSE 374 Final Exam Sample Solution 6/10/10

Week 5, continued. This is CS50. Harvard University. Fall Cheng Gong

Dynamic Data Structures. CSCI 112: Programming in C

CSE au Final Exam December 12, 2018

CS 5513 Entry Quiz. Systems Programming (CS2213/CS3423))

Intermediate Programming, Spring 2017*

Ricardo Rocha. Department of Computer Science Faculty of Sciences University of Porto

Final CSE 131B Spring 2004

Memory Corruption 101 From Primitives to Exploit

Fall 2018 Discussion 2: September 3, 2018

C BOOTCAMP DAY 2. CS3600, Northeastern University. Alan Mislove. Slides adapted from Anandha Gopalan s CS132 course at Univ.

C++ for Java Programmers

Dynamic memory allocation (malloc)

Transcription:

Question 1. (20 points) C programming. For this question implement a C function contains that returns 1 (true) if a given C string appears as a substring of another C string starting at a given position. Examples: The following should return 1 (true): contains("abc","abc",0); contains ("bc","abc",1); contains("xyz","xyzzy",0). The following calls return 0 (false): contains("abc","xyz",1); contains("abc","abcde",1); contains("def","abcde",3); contains("de","abcde",1). Restriction: the only function you may use from the <string.h> library is strlen. Simplifying assumptions: Assume that pointer arguments are non-null and point to properly '\0'-terminated C strings that have at least one character in them besides the terminating '\0'. You may also assume that pos is non-negative (i.e, pos>=0). // return 1 if string s appears in target starting at pos int contains (char *s, char *target, int pos) { // return false immediately if s runs past end of // target starting at loc if (pos + strlen(s) > strlen(target)) // Compare characters of s to target+pos. If they differ // then the strings don't match. If we get to the \0 // byte at the end of s, then everything matched char *sptr = s; char *tptr = target+pos; while (*sptr!= '\0') { if (*sptr!= *tptr) sptr++; tptr++; // all of s examined and no mismatch return 1; There are certainly many other solutions, including ones that look for a terminating \0 in both strings simultaneously, but there still needs to be some sort of check to be sure that pos is not so large that target+pos references beyond the \0 at the end of target. Page 1 of 9

Question 2. (12 points) Here is a small header file and a main program that includes it. File midterm.h #ifndef _MIDTERM_H_ #define _MIDTERM_H_ #define NEW_PI PI+1 #define GOLDEN 1.618 #define NEWER_PI(x) (x*pi) typedef int number; #endif // _MIDTERM_H_ File midterm.c #include "midterm.h" #define PI 3.1415 #define GOLDEN 1.618+1 int main(int argc, char **argv) { number x = PI; int xx = NEW_PI; int y = GOLDEN; int z = NEWER_PI(y+1); Below, write the output produced by the C preprocessor (cpp or gcc -E) showing exactly how file midterm.c is rewritten and sent to the compiler phase of gcc. (The preprocessor can correctly process this file without any blocking errors.) typedef int number; int main(int argc, char **argv) { number x = 3.1415; int xx = 3.1415 +1; int y = 1.618+1; int z = (y+1*3.1415); Page 2 of 9

Question 3. (24 points) The somewhat traditional, always annoying C program. Consider the following program, which does compile and execute without any errors. (We assume for this question that malloc always succeeds and returns a non-null pointer.) #include <stdio.h> #include <stdlib.h> typedef struct point2d { // 2-d point int x, y; Point2d, *Point2dPtr; void PrPoint(char *label, Point2dPtr p) { printf("%s %d %d\n", label, p->x, p->y); Point2dPtr NewPt(int a, int b) { Point2dPtr p = (Point2dPtr)malloc(sizeof(Point2d)); p->x = a; p->y = b; return p; void Shuffle(Point2d a,point2dptr x,point2dptr y,point2dptr *z) { *z = y; *x = *y; **z = a; //// HERE //// int main() { Point2dPtr p1 = NewPt(1, 2); Point2dPtr p2 = NewPt(3, 4); Point2dPtr p3; Shuffle(*p1, p1, p2, &p3); PrPoint("p1", p1); PrPoint("p2", p2); PrPoint("p3", p3); Answer questions about this program on the next page. You may remove this page for reference if you wish. Page 3 of 9

Question 3. (cont.) (a) (15 points) Draw a boxes n arrows diagram showing state of memory when control reaches the comment containing //// HERE //// in the middle of function Shuffle. Your diagram should have boxes showing the stack frames for all active functions. The stack frames should show values of all local variables. Draw each point2d struct as a box with two labeled fields x and y. Draw an arrow from each pointer to the location that it references. Data that is allocated on the heap should be drawn in a separate area, since it is not part of any function stack frame After drawing your diagram, be sure to answer part (b) at the bottom of the page. Shuffle a x y z x 1 y 2 heap x 1 3 y 2 4 main p1 x 3 1 y 4 2 p2 p3 (b) (9 points) What output does this program produce when it is executed? p1 3 4 p2 1 2 p3 1 2 Page 4 of 9

Question 4. (24 points) Here is an attempt to fix the buggy vector program. Be sure to read the rest of the question before tearing out any pages or doing any work.... 1 #include <stdbool.h> // for bool 2 #include <stdlib.h> // for malloc, free 3 4 #define INIT_VEC_SIZE 8 5 #define FINAL_VEC_SIZE 10 6 7 typedef void* element_t; 8 9 typedef struct vector_t { 10 size_t length; // length of arry 11 element_t *arry; // data items unused entries are NULL 12 *vector_t; 13 14 // Fill the array in v with the elements 0 to n-1 15 // Return true if it succeeds 16 bool FillElements(size_t n, vector_t v); 17 18 // Create a vector and then add some values to the vector array 19 int main(int argc, char *argv[]) { 20 21 // allocate initial vector and exit if failure 22 vector_t v = (vector_t)malloc(sizeof(struct vector_t)); 23 if (v == NULL) 24 return EXIT_FAILURE; 25 v->arry = (element_t*)malloc(init_vec_size *sizeof(element_t)); 26 if (v->arry == NULL) { 27 free(v); 28 return EXIT_FAILURE; 29 30 31 // save length in vector struct and initialize array elements 32 v->length = INIT_VEC_SIZE; 33 bool success = FillElements(FINAL_VEC_SIZE, v); 34 if(!success) 35 return EXIT_FAILURE; 36 37 38 // fill the array in v with the elements 0 to n-1 39 // return true if successful 40 bool FillElements(size_t n, vector_t v){ 41 size_t i; 42 43 // store new int objects in so vector[i] holds int i. 44 // exit if any step fails. 45 for (i = 0; i < FINAL_VEC_SIZE; ++i) { 46 int *x = (int*)malloc(sizeof(int)); 47 if (x == NULL) 48 return false; 49 *x = i; 50 v->arry[i] = x; 51 52 return true; 53 Page 5 of 9

Question 4. (cont.) There seem to be some memory problems, so we ran this program using valgrind. Here s the output we got: Memcheck, a memory error detector Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info Command:./buggy Invalid write of size 8 at 0x400671: FillElements (buggy.c:50) by 0x4005FB: main (buggy.c:33) Address 0x4c2a0d0 is 0 bytes after a block of size 64 alloc'd at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x4005B4: main (buggy.c:25) HEAP SUMMARY: in use at exit: 120 bytes in 12 blocks total heap usage: 12 allocs, 0 frees, 120 bytes allocated 8 bytes in 2 blocks are definitely lost in loss record 1 of 4 at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x40063B: FillElements (buggy.c:46) by 0x4005FB: main (buggy.c:33) 112 (16 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x400598: main (buggy.c:22) LEAK SUMMARY: definitely lost: 24 bytes in 3 blocks indirectly lost: 96 bytes in 9 blocks possibly lost: 0 bytes in 0 blocks still reachable: 0 bytes in 0 blocks suppressed: 0 bytes in 0 blocks For counts of detected and suppressed errors, rerun with: -v ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 2 from 2) Your job is to find all of the bugs in the program and indicate how to fix them. Use the information in the program itself as well as the valgrind output to locate the bugs (and it may be that there are some bugs that don t result in any error report from valgrind, so be sure to check the source code carefully). You can either mark the original program to show what s wrong and how to fix it, or you can write an explanation on the following page. Feel free to detach this page (with the valgrind output) while you work, but be sure to turn in the page with the program code if you mark your answers there. Page 6 of 9

Question 4. (cont.) You can use the space on this page for your answer if you wish, or you can mark your answers on the program code. Just be sure the grader can follow what you ve done to give you as much credit as possible. Here are the bugs that were deliberately introduced into the code. We tried to allow generous partial credit, particularly if you missed subtle points. If the malloc in FillElements fails, any elements of the array that were previously allocated need to be freed before returning false The elements of the array, the array, and the vector need to be freed at the end of main If FillElements returns false, the array and vector need to be freed in main In order to fill n elements, the array needs to be resized if it is not large enough. After freeing the old array and allocating space for the new array (malloc or realloc), there should be a check to see if the allocation succeeds and return false if it doesn t. If allocation succeeds, v->length needs to be updated. in FillElements, unused elements of the array need to be initialized to NULL if n is less than the size of the array. In FillElements, the for loop initializes FINAL_VEC_SIZE elements. It should be n. The end of main is missing return EXIT_SUCCESS. An additional, subtle point: Many people felt there was an error in this line of code: vector_t v = (vector_t)malloc(sizeof(struct vector_t)); The subtlety is that the name vector_t has two distinct meanings in the code. One is as a struct tag name, while the other is a typedef name that is a synonym for struct vector_t * (i.e., pointer to struct vector_t). These two definitions are distinct and it depends on context to decide which one applies. So in the above code, the first two uses of vector_t are the pointer type, while the use of vector_t in the sizeof expression is the struct tag, and it is correct. Changing the code so it reads malloc(sizeof(vector_t)) would allocate space sufficient to store a pointer, but not enough for the struct. Page 7 of 9

Question 5. (20 points) A little C++ programming. We ve been having so much fun with linked lists, it seemed a shame not to do a bit more in C++. Here is the header for a class that implements a list of C++ strings using a single-linked list made up from StringNode objects. #include <string> using namespace std; class StringNode { // single node in a linked list of strings public: string value_; // value in this node StringNode * next_; // next node in the list or nullptr if none // convenience constructor - initialize new node with string s // and next pointer p StringNode(string s, StringNode *p): value_(s), next_(p) { ; class StringLinkedList { public: // construct empty StringLinkedList StringLinkedList() : first_(nullptr), last_(nullptr) { // additional operations omitted... private: StringNode * first_; StringNode * last_; ; // first node in list // last node in list // first_ = last_ = nullptr if the // list is empty. You should assume that all dynamic memory allocation and deletion functions will succeed without errors you do not need to check for failures or handle exceptions. You can remove this page for reference while working on the question if you wish. Page 8 of 9

Question 5. (cont.) We would like to add a += assignment operator to this class to append new strings to a list. If lst is an object of type StringLinkedList, then the operation lst+=s should create a new node holding the C++ string s and add it (append it) as the last node of the list lst. (a) (5 points) Give the declaration for this new += operation to be added to the declaration of class StringLinkedList (above). StringLinkedList &operator+=(const string &s); (b) (15 points) Give the full implementation of this added += operation as it would appear in a separate source file StringLinkedList.cc. Your answer should contain any necessary #include or other compiler and preprocessor directives needed. #include "StringLinkedList.h" #include <string> using namespace std; StringLinkedList &StringLinkedList::operator+=(const string &s) { // allocate new node StringNode * p = new StringNode(s,nullptr); // if list is empty this is now the first node if (first_ == nullptr) { first_ = last_ = p; else { // add to end of list and link to former last node last_->next_ = p; last_ = p; // return reference to this StringLinkedList return *this; Some solutions omitted #include <string> or using namespace std;, probably assuming that since these were already found in the StringLinkedList header they would be indirectly included anyway. But every file should normally #include all header files that it references, both for documentation and to avoid problems if some of the headers it uses are later changed and no longer #include the same files or have the same using directives that they did previously. Page 9 of 9