CSCI 3300
Section 001
Fall 2005
Solutions to practice questions for quiz 2

  1. True or false.

    1. A dangling pointer is pointer to memory that has been deleted, or that you do not own. True.

    2. Storing a value at a memory address that is a dangling pointer can cause some minor problems, but the program usually recovers from them quickly. False. In fact, storing a value at a dangling pointer can cause unpredictable but usually very bad consequences for a program.

    3. If a C++ program does not return memory in the heap to the free space pool when it is done with the memory, then the system will periodically sweep through memory and return unused memory to the free space pool automatically. False. It is up to you recycle memory in the heap that you no longer need.

  2. If p has type T* then what is the type of *p? Expression *p has type T

  3. C++ notation p->x abbreviates

    1. (p*).x
    2. (*p).x
    3. (p.x)*
    4. p.(*x)

  4. C++ notation p[k] abbreviates

    1. p + k
    2. p + *k
    3. (*p) + k
    4. *(p + k)
    5. *p + *k

  5. Suppose that you have allocated a Frog as follows.

        Frog* p = new Frog;
    If you compute with the Frog for a while and then want to recycle the memory occupied by this Frog, which of the following statements should you use?

    1. delete p;
    2. delete *p;
    3. delete Frog p;
    4. delete Frog *p;
    5. You should not ever try to delete this memory yourself.

  6. Suppose that you have allocated an array of Frogs as follows.

        Frog* p = new Frog[20];
    If you compute with this array for a while and then want to recycle the memory that it occupies, which of the following statements should you use?

    1. delete p;
    2. delete[] p;
    3. delete Frog[] p;
    4. delete Frog[] *p;
    5. You should not ever try to delete this memory yourself.

  7. Suppose that you have allocated a Frog as follows.

        Frog f;
    If you compute with this Frog for a while and then want to recycle the memory occupied by this Frog, which of the following statements should you use?

    1. delete f;
    2. delete *f;
    3. delete Frog f;
    4. delete Frog *f;
    5. You should not ever try to delete this memory yourself.

  8. Suppose that the following structure definition is given.

       struct Widget
       {
         int side;
         char bottom[22];
         Widget(int s, char* b)
         {
           side = s;
           strcpy(bottom, b);
         }
       };
    (The strcpy function copies a null-terminated string into another array. strcpy(bottom,b) copies b into array bottom.)
    1. Show how to create a new Widget called frodo with side = 4 and bottom = "blue". Use the constructor. Build the Widget in the run-time stack.

            Widget frodo(4, "blue");
          

    2. Show how to build the same Widget as in (a), but this time in the heap. Make frodop be a pointer to the Widget.

            Widget* frodop = new Widget(4, "blue");
          

    3. Suppose that the constructor were not provided as part of the Widget structure type. Show how to create the same Widget frodo without using the constructor. Build frodo in the run-time stack.

            Widget frodo;
            frodo.side = 4;
            strcpy(frodo.bottom, "blue");
          

    4. Build frodop, as in part (b), but assuming that the constructor is not included in the definition of Widget.

            Widget* frodo = new Widget;
            frodo->side = 4;
            strcpy(frodo->bottom, "blue");
          

  9. Suppose that a linked list is built from list cells, where each cell has the following type.

        struct ListCell
        {
          ListCell* next;
          int item;
          ListCell(int i, ListCell* n)
          {
            next = n;
            item = i;
          }
        };
    Write a definition of a function that will compute the sum of all of the numbers in a linked list. The sum of an empty list is defined to by 0. A heading is given.

    Here are two solutions.

          int sum(ListCell* L)
          {
            if(L == NULL) return 0;
            else return L->item + sum(L->next);
          }
      
          int sum(ListCell* L)
          {
            ListCell* p = L;
            int result = 0;
    
            while(p != NULL) 
            {
              result = result + p->item;
              p = p->next;
            }
            return result;
          }
      
    Remark. The first solution uses recursion, so sum calls (a copy of) itself. Notice that it does not include a loop as well. The second solution uses a loop. It is not also recursive. Use one or the other, not both at once.

    The recursive version has two cases, one for a null list, and one for a nonnull list. The case for a nonnull list uses the same function on the rest of the list (L->next) after the first member.

    In the loop solution, you need to change the values of variables. The recursive solution does not change the values of any variables. In recursive solutions, you rarely need to change anything.

  10. Using the ListCell type from the preceding question, write a function that returns the first positive number in a given list. That is, it looks through the list and returns the first number that it finds that is positive. If there are no positive numbers, it should return 0.

    Here are two solutions.

        int firstPositive(ListCell* A)
        {
          if(A == NULL) return 0;
          else if(A->item > 0) return A->item;
          else return firstPositive(A->next);
        }
      
        int firstPositive(ListCell* A)
        {
          ListCell* p = A;
          while(p != NULL) 
          {
            if(p->item > 0) return p->item;
            p = p->next;
          }
          return 0;
        }
      

  11. Using the ListCell type from the preceding question, write a function that takes two lists, and tells whether the two contain exactly the same numbers, in the same order. It should return true if they are the same, and false if they are different.

    Here are two solutions.

        bool sameList(ListCell* A, ListCell* B)
        {
          if(A == NULL) return B == NULL;
          else if(B == NULL) return false;
          else return A->item == B->item && sameList(A->next, B->next);
        }
      
        bool sameList(ListCell* A, ListCell* B)
        {
          ListCell *pA, *pB;
          pA = A;
          pB = B;
          while(pA != NULL && pB != NULL) 
          {
            if(pA->item != pB->item) return false;
            pA = pA->next;
            pB = pB->next;
          }
          if(pB == NULL && pA == NULL) return false;
          else return true;
        }