Last Updated: 2019-06-17 Mon 16:30

CSCI 2021 Lab04: Review for Exam 1

CODE DISTRIBUTION: lab04-code.zip

  • Download the code distribution every lab
  • See further setup instructions below

CHANGELOG:

1 Rationale

This lab reviews concepts from earlier labs and lecture to prepare for an exam. Lab leaders will give time to work, answer questions on the review problems here, and lead discussion of solutions to them. You may also discuss the solutions to the Practice Exam with your lab leader to help prepare for the exam.

Associated Reading / Preparation

  • C References: Basics of C programming including control structures, pointers/addresses, memory allocation/deallocation, bit operations
  • Bryant and O'Hallaron: Ch 2.1-2.3 on binary representations of integers in unsigned and two's complement signed format.

Grading Policy

Credit for this lab is earned by taking the associate Lab Quiz which is linked under Canvas / Quizzes. The quiz will ask that you upload your completed QUESTIONS.txt document and then take a short quiz on the material covered in the lab.

See the full policy in the syllabus.

2 Codepack

The codepack for the lab contains the following files:

File Description
QUESTIONS.txt Questions to answer
dog_diagram.c C file for Problem 1
badmem.c C file for Problem 2
best_score.c C file to complete for Problem 3
scores1.txt Data file for Problem 3
scores2.txt Data file for Problem 3
scores3.txt Data file for Problem 3
scores-empty.txt Data file for Problem 3

3 Questions

Analyze the files in the provided codepack and answer the questions given in QUESTIONS.txt.

                           __________________

                            LAB 04 QUESTIONS
                           __________________


- Name: (FILL THIS in)
- NetID: (THE kauf0095 IN kauf0095@umn.edu)

Answer the questions below according to the lab specification. Write
your answers directly in this text file and submit it to complete the
lab.


PROBLEM 1: Memory Diagram
=========================

  Examine the code in dog_diagram.c which uses a couple simple functions
  with a struct.
  ,----
  |  1  #include <stdio.h>
  |  2  typedef struct{
  |  3    int age;
  |  4    double weight;
  |  5    char name[8];
  |  6  } dog_t;
  |  7  
  |  8  void init_dog(dog_t *d){
  |  9    strcpy(d->name, "Rolf");
  | 10    d->age = 0;
  | 11    d->weight = 5.0;
  | 12    ////// POSITION A
  | 13    return;
  | 14  }
  | 15  
  | 16  void birthday(int num, dog_t *d){
  | 17    int next = d->age + num;
  | 18    if(next < 3){
  | 19      d->weight += 10.0;
  | 20    }
  | 21    ////// POSITION B
  | 22    d->age = next;
  | 23    return;
  | 24  }
  | 25  
  | 26  int main(){
  | 27    dog_t dog;
  | 28    init_dog(&dog);
  | 29    double curwgt = dog.weight;
  | 30    birthday(2, &dog);
  | 31    printf("%s gained %f pounds\n",
  | 32           dog.name, dog.weight-curwgt);
  | 33    return 0;
  | 34  }
  `----

  Fill in the memory diagrams below for the layout of memory if
  execution stops at the positions given in the comments.


POSITION A
----------

  ,----
  | |------------+-------------+-------+-------|
  | | Frame      | Sym         | Addr  | Value |
  | |------------+-------------+-------+-------|
  | | main()     | curwgt      |       |       |
  | | line:28    | dog.name[7] |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             |       |       |
  | |            |             | #1208 |       |
  | |            | dog.weight  | #1200 |   5.0 |
  | |------------+-------------+-------+-------|
  | | init_dog() | d           |       |       |
  | | line:??    |             |       |       |
  | |------------+-------------+-------+-------|
  `----


POSITION B
----------

  ,----
  | |------------+------------+-------+-------|
  | | Frame      | Sym        | Addr  | Value |
  | |------------+------------+-------+-------|
  | | main()     | curwgt     |       |       |
  | | line:??    |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            |       |       |
  | |            |            | #1208 |       |
  | |            | dog.weight | #1200 |       |
  | |------------+------------+-------+-------|
  | | birthday() |            | #1192 |       |
  | | line:??    |            |       |       |
  | |            |            |       |       |
  | |------------+------------+-------+-------|
  | 
  `----


PROBLEM 2: Valgrind Debugging badmem.c
======================================

  The file badmem.c has functions main() and set_pn() in it but has a
  bad memory problem associated with it.  A sample compile and run is as
  follows.

  ,----
  | > gcc -g badmem.c
  | > a.out
  | Segmentation fault (core dumped)
  `----


A
~

  Below is some output from Valgrind. Explain the errors that are
  identified by Valgrind and inspect the source code of badmem.c to
  discover the source of the error. Clearly identify whether there is a
  problem in main() or set_pn().

  ,----
  | > valgrind ./a.out
  | ==15611== Memcheck, a memory error detector
  | ==15611== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
  | ==15611== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
  | ==15611== Command: ./a.out
  | ==15611== 
  | ==15611== Use of uninitialised value of size 8
  | ==15611==    at 0x10873B: set_pn (badmem.c:40)
  | ==15611==    by 0x1086B8: main (badmem.c:20)
  | ==15611== 
  | ==15611== Invalid write of size 4
  | ==15611==    at 0x10873B: set_pn (badmem.c:40)
  | ==15611==    by 0x1086B8: main (badmem.c:20)
  | ==15611==  Address 0x5 is not stack'd, malloc'd or (recently) free'd
  | ==15611== 
  | ==15611== 
  | ==15611== Process terminating with default action of signal 11 (SIGSEGV): dumping core
  | ==15611==  Access not within mapped region at address 0x5
  | ==15611==    at 0x10873B: set_pn (badmem.c:40)
  | ==15611==    by 0x1086B8: main (badmem.c:20)
  | ==15611==  If you believe this happened as a result of a stack
  | ==15611==  overflow in your program's main thread (unlikely but
  | ==15611==  possible), you can try to increase the size of the
  | ==15611==  main thread stack using the --main-stacksize= flag.
  | ==15611==  The main thread stack size used in this run was 8720384.
  | ==15611== 
  | ==15611== HEAP SUMMARY:
  | ==15611==     in use at exit: 0 bytes in 0 blocks
  | ==15611==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
  | ==15611== 
  | ==15611== All heap blocks were freed -- no leaks are possible
  | ==15611== 
  | ==15611== For counts of detected and suppressed errors, rerun with: -v
  | ==15611== Use --track-origins=yes to see where uninitialised values come from
  | ==15611== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
  | Segmentation fault (core dumped)
  `----


B
~

  Fix badmem.c so that it works correctly. Your fix should NOT change
  the prototype for the set_pn() function but can make other adjustments
  to local variables.


PROBLEM 3: Best Score in File
=============================

  A grading file has scores for an exam formatted as in the following
  example:
  ,----
  | Darlene 91.0
  | Angela  76.5
  | Elliot  94.5
  | Tyrell  87.5
  | Dom     70.0
  | Phillip 55.5
  `----
  The names of students are the first item followed by a numeric score
  on their programming exam.  Write `main()' function in the file
  `best_score.c' which
  - Opens the file
  - Reads through all the contents
  - Prints out the name and score of the highest scorer

  Make use of the following small struct in this exercise to ease the
  process of copying information as indicated.
  ,----
  | typedef struct {
  |   char name[128];               // name of student
  |   double score;                 // score on exam
  | } grade_t;
  | // struct which allows assignment of name/score such as in
  | //   best = curgrade;
  | //   printf("best is now: %s %f\n", best.name, best.score);
  `----
  - Don't forget to close the file
  - Study the session below for special cases such as empty files

  ,----
  | > gcc -g best_score.c
  | > ./a.out 
  | usage: ./a.out <filename>
  | <filename> should have columns of names, numbers as in
  | Darlene 91.0
  | Angela  76.5
  | Elliot  94.5
  | Tyrell  87.5
  | Dom     70.0
  | Phillip 55.5
  | > ./a.out scores1.txt
  | Best score: Elliot 94.500000
  | > ./a.out scores2.txt 
  | Best score: Student13 90.800000
  | > ./a.out scores3.txt 
  | Best score: Student43 99.300000
  | > ./a.out scores-empty.txt
  | file was empty
  | > ./a.out no-such-file.txt
  | could not open the file
  `----

4 What to Understand

Ensure that you have a good understanding of C programming, memory layout, and the binary representations of integers.


Author: Chris Kauffman (kauffman@umn.edu)
Date: 2019-06-17 Mon 16:30