CMPSC 311, Spring 2013, Midterm Exam 2, Sample questions for review

The second midterm exam will be Wednesday, Mar. 27, 6:30 - 7:45 pm, in 110 Wartik and 111 Wartik.
Anyone who has a conflict with the scheduled time, especially another class or exam the same night, should have asked about a conflict exam already.  Time and place information has been sent to you by email.

The exam is closed book, closed computer, closed neighbor, no cell phones, etc.  But, you can bring two 8 1/2 x 11 sheets of paper, with your name on both, as a "cheat sheet"; turn these in with the exam.

Class time on Wednesday, Mar. 27, will be devoted to review only.  Project solutions are posted on ANGEL.



The exam will ask questions about general knowledge of C and Unix, and will require both programming and debugging.  Any material that was covered in class, as assigned reading, as background for the projects, or in the projects, could be on the exam.  In particular, don't neglect the programming examples in the Intro to Unix notes, or the exercises in the notes.  The "cheat sheet" could remind you of Unix function prototypes and C syntax, but you should be able to answer most questions without referring to it.

The questions will be
The actual number of points in each category might be different, but not by much.

The topics covered will be
Some of the sample questions here are harder than are actually on the exam.



1.  How many of these statements are correct?

       *   Variables allocated in the data segment are always initialized.
       *   Variables allocated in the stack segment are always initialized.
       *   Variables allocated in the heap segment are always initialized.
       *   Variables allocated in the text segment are always initialized.

      (1) none, they are all incorrect or nonsense
      (2) one
      (3) two
      (4) three

2.  Explain the various parts of the (syntactically correct) declaration

    const volatile unsigned long int * const controller = 0xFFFFFF28;

3.  True/False, circle T or F. 
 
  T  F  (a)  By convention in Unix command shells, file descriptor 0 refers to the standard input of a process.
 
  T  F  (b)  There is a limit on the current number of open files that a process can have.
 
  T  F  (c)  There is a limit on the total number of files that a process can have opened over the course of its execution.

  T  F  (d)  It would be a good idea for stderr to be a fully buffered output stream.

  T  F  (e)  When a process exits, all its open files are closed.
 
4.  The read() function normally returns the number of bytes obtained from an open file, but it could also return -1 to indicate an error.  Write a short code sequence to print a message describing the error, if an error has actually occurred.

5.  Some Unix functions return early when a signal is received, without completing their requested action, but without actually encountering an error.  Write a short code sequence that will reliably wait for a specific child process to exit.

6.  Somewhere in the Solaris include files this line appears:

    #define getc(p) (--(p)->_cnt < 0 ? __filbuf(p) : (int)*(p)->_ptr++)

Explain it.  [You need to make "educated guesses" about _cnt, _filbuf and _ptr,  and be careful with the operator precedence rules.  Start with the obvious assumption that the type of p is FILE * .]



Here's a cute little program:

#include <stdio.h>

int main(void)
{
  const int foo = 1;
  printf("%d\n", foo);

  *(int *)&foo = 2;
  printf("%d\n", foo);

  return 0;
}

What happens when the program is compiled and run?  If we move the declaration of foo from local in main() to global, what happens when the program is compiled and run?



Write a code sequence to open a file, read its contents, determine whether the file contains a line of text longer than 80 characters (not including the line-terminating newline character), then print "yes" or "no" as appropriate, and close the file.  Partial credit for pseudo-code is possible.

Note that "yes" or "no" should be printed only once.  Assume the usual Unix text file convention for end-of-line, and ASCII characters.



Explain why this function has a serious bug, or displays a serious flaw in the programmer's logic.  Its intent is to allocate memory.

char * blat(size_t n)
{
  char a[n];
  /* assign values to elements of a[], or maybe not */
  return a;
}

Explain why this function has a serious bug, or displays a serious flaw in the programmer's logic.  Its intent is to allocate and initialize memory.

void blat(size_t n)
{
  char *a = malloc(n);
  for (int i = 0; i < n; i++)
    a[i] = 0;
}