CS62 - Spring 2011 - Lecture 35

  • administrative
       - keep looking at the exercises

  • A quick review of some terminology
       - in Java we have two types of variables/values
          - built-in types (int, double, float)
          - references to objects
       - in C++, we have three types
          - built-in types
          - pointers to objects (e.g. references to objects)
             - int*
             - vector<int>*
             - BinaryTree*
          - objects that are on the stack
       - an "operator" is a special symbol that performs a specific operation on one, two or three operands and returns a result
          - what operators have we seen?
       - When dealing with pointers, we have three operators that come up:
          - * dereferences a pointer and returns the actual object/value pointed to by the pointer
             - int* x;
                - *x (gives us the value pointed to by x)
             - vector<int>* v
                - *v (gives us the vector point to by v)
          - -> accesses members of the object pointed to by the pointer
             - vector<int>* v
                - v->push_back(10)
                - v->size()
             - BinaryTree* b
                - b->size()
          - & gives us the memory location (or a reference to) where a variable is stored
             vector<int> v;
             vector<int>* vPtr = &v;
       - parameter passing
          - when calling a function, we have the actual parameters
             - f(2, 3)
             - f(2+5, 7)
             - f(x, y)
          - and we have the formal parameters
             - f( int x, int y )
             - f( vector<int>* x )
          - parameter passing is how the actual parameters get bound to the formal parameters
          - there are three types of parameter passing in C++:
             - call by value
                - the actual parameters get copied
                   - for built-in types, this just means copying the value
                   - for objects, this means calling the copy constructor and creating a new object
             - call by reference
                - the actual parameters and the formal parameters are the same thing
                - rather than copying, the formal parameters become an alias (or another name) for the actual parameters
                - this is denoted by placing an '&' after the type in the formal parameter list
                   - NOTE: this is DIFFERENT from the & operator
                   - the type is still the original type
                      - BinaryTree& is different than BinaryTree*
             - call by constant reference
                - same as above, except we can't modify the parameters in the method
       - return approaches
          - similarly, we can specify how things are returned from a function/method

  • look at linkedlist.cpp code
       - should be similar to the code you wrote in lab
       - look at test2 in linkedlisttest.cpp
          - what did your answer print out?
             L: 9 8 7 6 5 100 3 2 1 0
             L2: 9 8 7 6 5 100 3 2 1 0
          - why?
             - because we used the default copy constructor, which does a shallow copy of the data
             - the default copy constructor would just copy the pointer value of head
             - l and l2 would refer to the same chain of Nodes
       - what if we wanted it to do a deep copy?
          - add a copy constructor that traverses the Node chain and copies it
       - look at linkedlistimproved.cpp code
          - added both the copy constructor and the = operator
             - almost always if you add one, you're going to need the other
          - look at the copy constructor... often we can reuse code
          - look at the = operator
             - clear (that is, empty) the linked list
             - copy it over a node at a time

  • memory management
       - in general, EVERY time you create an object on the heap using "new" you should make sure that you're calling delete appropriately somewhere else in your code
       - memory management is hard!
       - pitfalls
          - memory leak (forgetting to delete an object)
          - deleting memory before it's actually freed up
             vector<int>* v = new vector<int>;
             vector<int>* v2 = v;
             delete v;
             v2->push_back(10);

             - look at example in problems.cpp code
                - what will this do/print out?
          - double deleting memory
             vector<int>* v = new vector<int>;
             vector<int>* v2 = v;
             delete v;
             delete v2;

  • does our linked list code correctly handle memory?
       - no!

  • write removeFirst() to correctly handle memory deletion

  • Can we use this method to write our clear method?
       - look at clear() method in linkedlistimproved.cpp code
          - recursively removing elements from the list until it's empty
       - look at removeFirst() method in linkedlistimproved.cpp code