Project 1: Sorted Square List with Circular Buffers

Due: Friday, February 23, 8:59:59pm

Links: [Project Submission] [Late Submissions] [Project Grading] [Grading Guidelines] [Academic Conduct]

Change Log

Modified items are in highlighted in blue and orange colors.

[Saturday Feb 24, 07:30pm] The submission instructions have been fixed to reflect the complete set of test programs released, and include modified instructions for compiling them.

[Monday Feb 19, 02:40pm] The descriptions of the SortedSquareList functions find() and findAt() incorrectly declared them as returning void; they have been corrected to "int". (The declarations in SortedSquareList.h were correct.)

[Sunday Feb 18, 02:50pm] The first set of test programs have been released–see the section "Test Programs".

[Friday Feb 16, 05:35pm] A small modification to the last part of the "removing an entry" algorithm: we added an IF-condition to the final ELSE (the "shift in from the right side by default" action). Also, those instructions were reformatted to look more like pseudocode to help you follow it, and a typo was fixed in the next paragraph. (Changes are blue-highlighted; NOTE: your browser probably also displays all links as blue; none of those were changed.)

[Wednesday Feb 14, 05:12pm] Several small hints and clarifications added. (These changes are orange-highlighted.)


Objectives

The objective of this programming assignment is to have you review C++ programming using following the features: object-oriented design, dynamic memory allocation (of arrays) and pointer manipulation.

Introduction

Note: Circular Buffers are described in Section 5.2.4 of our textbook (p. 211). Please read that section before proceeding.

An interesting, relatively straightforward data structure is the square list: it is meant to impose the semantics of a linear list of values with ordering, but is internally implemented as a "square" structure, i.e. a conceptual two-dimensional array, except more dynamic. The classic version does not use arrays at all, instead building a linked list of linked lists. It starts with a top-level linked list, each node of which points to a secondary linked list that represents an ordered sequence of values, one stored per node. The idea is that there is enough information in the nodes of the top-level linked list to allow us to bypass entire sublists while searching for the value that we want, finally only searching the values of one sublist instead of the entire list. In order to guarantee efficiency, we must keep the lengths of all of the sublists relatively equal. The definition of "relatively equal" varies among algorithms, but in all cases is designed to put constraints on the variance so that we compute firm bounds on the runtime for all of the operations on the list.

A good description of one implementation of a square list using linked lists is given in the Fall 2013 CMSC 341 Project 1 description here. You should review that project description. That version demonstrates how the square list allows someone to fetch, modify, remove or add a value at a specific position in the list, specified as a numerical index, all in O(√n) time. An array would take a longer O(n) time for the add and remove operations, and a simple linear linked list would take O(n) all of these four.

The linked list-based square list has certain desirable performance characteristics which derive from fundamental properties of linked lists in general: very fast insertion and deletion, and small, independent units of allocation/deallocation. Linked lists also support a concept of ordering: you can deterministically reference the n-th object in the list. The one flaw of a linked list is that it does not efficiently support direct indexing like an array does: you must walk the list link-by-link to get to that n-th object, which is expensive. The linked list square list is just using a trick to decrease the lengths of the lists it must walk.

Our version of the square list for this project, while having similar functional goals, will be a completely different implementation. Specifically, we want to support additional functionality, as well as better performance goals for some of the operations.

Your goal for this project will be to implement a square list with the following requirements:l

Warning: you should check that the column isn't already at capacity before inserting the new value, and handle it appropriately if it is. This also applies as you shift values: shifting a value into a column might exceed its capacity. Note that the condition is temporary: any column where adding a new value would exceed its capacity would also be exceeding the SD, and you would therefore be immediately shifting a value out the other end; however, the column cannot even temporarily hold extra data. You must anticipate this potential overflow and do the shift out before doing the shift in.

When removing an entry, we do roughly the opposite of the operations for adding a value. After finding and removing the entry from the column, we check to see if the resulting length is less than the lower limit: SD - 1. If it is, we resolve this violation by shifting in one of the entries from an adjacent column, using the following strategy:

  1. For the first shift:
    • IF (either side has a column that is at its upper limit, i.e., == SD)
      shift in from that side (choosing the right if both sides qualify);
    • ELSE IF (either side has a column below the minimum (SD - 1))
      shift in from that side;
    • ELSE IF (not an end column)
      shift in from the right side by default
    • (implied final ELSE: do nothing; the column just became (or already was) the one short end column)
  2. The shift might have caused the donatingreceiving column to in turn drop below the SD - 1 lower limit, in which case we would execute a shift again, possibly multiple times, from the same direction as the first shift.
  3. The last column might end up being short: this is okay.
  4. If the first or last column drops to length 0, we must remove the column from the outer list. This does not mean the SSLColumn object is actually deleted: it fact, it must be left as-is, because we might need it again shortly. We instead "remove" the column from the top-level circular buffer by updating the m_last (or m_first, as the case may be) and m_size data members to indicate it is no longer in the set of active columns.
  5. Adding and removing are the only operations that alter the shape of the square list, and the above instructions will restore the desired shape.

    Allocation Strategy

    Since all our storage will be in the form of arrays (an array of SSLColumn pointers in the SortedSquareList object, and an array of ints in each SSLColumn object), we have to worry about how large to allocate each array. We will start off dimensioning each at 2, allowing us to store up to 4 values. If the user tries to add a 5th value, we will grow it to a 4x4 array-of-arrays, then 8x8, 16x16, 32x32, and so on. The pattern is to double the dimensions each time, which will quadruple the capacity with each expansion. (This is similar to the growth strategy of most implementations of the vector class, except being 1-dimensional, they only double the capacity each round.) This exponential strategy gives us what is known as amortized constant time cost for copying the elements from the old to the new.

    So when do you trigger the resizing? When adding a new value to the square list, you would first compare the old size to the current capacity, and if it's at the limit, you must grow before adding the new value. Growing consists of allocating a new top-level buffer, allocating all new columns of the newly increased dimension, then copying all the elements over column-by-column. This will result in half of the new columns being half-full, and the other half not being used at all yet. Since everything is a circular buffer, there's no need to try to match the positions: just copy your N old columns into the lower N columns of the new list, and for each column, copy the values into the first N elements of the larger array. You must be careful about making sure you delete all of the old data structures: you are sure to have a memory leak or two at first.

    NOTE: we never shrink the square lists, even if enough data is removed to allow us to do so. This makes life much easier for you.


    Assignment

    Note: Running time is one of the most important considerations in the implementation of a data structure. Programs that produce the desired output but exceed the required running times are considered wrong implementations and will receive substantial deductions during grading.

    Your assignment is to implement the variant of the square list data structure described above: a version that is structured as a circular buffer of circular buffers. To repeat a prohibition from above: you must build it using only primitive data structures, plus classes of your own design. You many not use vectors or any other classes from the C++ STL collection, nor any classes or data structures acquired from the web or from associates. Violating this will likely cause you to receive a failing grade on the project.

    For this project, we are detailing much of the requirements for the overall structure and behavior of your data structure, so you will have limited high-level design choices. There will be plenty of design work to do on the low-level implementation details, though.

    You are required to use the class definitions given in SSLColumn.h and SortedSquareList.h. (Specifications are given below.) The SSLColumn class is an implementation of a simple circular buffer of int values. The SortedSquareList class is the backbone circular buffer that manages the list of SSLColumn objects representing the columns of data.

    // file: SSLColumn.h // // UMBC CMSC 341 Spring 2018 Project 1 // // Header file for SSLColumn ("sorted square list column") // This is mostly an implementation of a circular buffer // See project description for details. // // Unless otherwise noted, any position argument is relative to // the stored data, and not an absolute index into the underlying array. // #ifndef _SSLCOLUMN_H_ #define _SSLCOLUMN_H_ class SSLColumn { public: // Constructor, default size is 2 SSLColumn(int n=2); // Copy constructor // Makes exact copy, including relative positions in circular buffers SSLColumn(const SSLColumn& other); // Destructor ~SSLColumn(); // overloaded assignment operator // We can copy into differently-sized array. Copying done in-place if // target has sufficient capacity; else, target's internal array // will be reallocated to a larger size. const SSLColumn& operator=(const SSLColumn& rhs) ; // Adds item to correct sorted order position in circular buffer. // Throws exception if out of room. // REQUIREMENT: must execute in O(n) time, where n is size of column void add(int data); // Adds item to top/left of circular buffer. // Throws exception if out of room. // REQUIREMENT: must execute in O(1) time void addFirst(int data) ; // Adds item to bottom/right of circular buffer. // Throws exception if out of room. // REQUIREMENT: must execute in O(1) time void addLast(int data) ; // returns position of item in column, -1 if not found. // REQUIREMENT: must execute in O(log(n)) time, where n is size of column int find(int data); // Retrieves value at index pos in circular buffer, based on sort order. // If pos == -1, retrieves last value in list, a la Python // Throws exception if pos >= size. // REQUIREMENT: must execute in O(1) time. int findAt(int pos); // Removes item from column, returning original position of item, // -1 if not found. // REQUIREMENT: must execute in O(n) time, where n is size of column int remove(int data); // Removes top/left item from circular buffer and returns it. // Throws exception if empty. // REQUIREMENT: must execute in O(1) time int removeFirst(void) ; // Removes bottom/right item from circular buffer and returns it. // Throws exception if empty. // REQUIREMENT: must execute in O(1) time int removeLast(void) ; // return maximum number of items this buffer can hold int capacity() ; // return number of items currently held in the buffer int size() ; // debugging function. Prints out contents. void dump(); // grading function used to examine private data members. // Do not implement! bool inspect (int* &buf, int &cap, int &size, int &start, int &end); private : int *m_data; // pointer to dynamically allocated array for buffer int m_capacity; // length of the allocated space pointed by m_data int m_size; // number of active items in buffer // index of the first active item in the buffer (virtual index 0) int m_start; int m_end; // index AFTER last active item in buffer // STUDENT-ADDED MEMBERS HERE ... ... // END STUDENT-ADDED MEMBERS }; #endif


    // file: SortedSquareList.h // // UMBC CMSC 341 Spring 2018 Project 1 // // Header file for Sorted Square List // See project description for details. // // Unless otherwise noted, any position argument is relative to // the stored data, and not an absolute index into the underlying array. // #ifndef _SORTEDSQUARELIST_H_ #define _SORTEDSQUARELIST_H_ #include "SSLColumn.h" class SortedSquareList { public: // default constructor SortedSquareList() ; // copy constructor SortedSquareList(const SortedSquareList& other) ; // destructor ~SortedSquareList() ; // overloaded assignment operator // We can copy into differently-sized square list, as long as it is large // enough to hold all of the actual stored data. const SortedSquareList& operator=(const SortedSquareList& rhs) ; // Adds item to correct position in square list, based on sort order. // Must grow dynamically allocated structures if we run out of room; // REQUIREMENT: must execute in O(sqrt(n)) time, where n is // number of items currently stored. void add(int data) ; // returns position of item in list, -1 if not found. // REQUIREMENT: must execute in O(log(n)) time int find(int data); // Retrieves value at index pos in square list, based on total sort order. // Throws exception if pos beyond end // REQUIREMENT: must execute in O(log(n)) time int findAt(int pos); // Finds and removes item from square list. // Returns true if data found, false otherwise. // REQUIREMENT: must execute in O(sqrt(n)) time bool remove(int data); // return maximum number of active items this square list can hold with // current allocation int capacity(); // Total number of items in the square list as a whole, across all columns. int size(); // debugging function, prints out contents of data structure void dump(); // grading function used to examine private data members. bool inspect (SSLColumn** &buf, int &cap, int &size, int &start, int &end); private : // Top-level array of pointers to SSLColumns. // Each entry of the array is a pointer. SSLColumn **m_cols; int *m_colInfo; // Useful for caching some info about each column int m_capacity; // length of the allocated space pointed by m_cols int m_size; // number of active columns in top-level buffer // index of first active column in the top-level buffer(virtual index 0); int m_start; int m_end; // index AFTER last active column in top-level buffer // STUDENT-ADDED MEMBERS HERE ... ... // END STUDENT-ADDED MEMBERS }; #endif


    Specifications

    Here are the specifics of the assignment, including a description for what each member function must accomplish.

    Requirement: Place the implementation of the SSLColumn member functions in a file called SSLColumn.cpp and the implementation of the SortedSquareList member functions in SortedSquareList.cpp.

    Requirement: All member functions must be implemented from scratch. In particular, you are not allowed to use any classes from the Standard Template Library (STL), not even vector.

    Requirement: You are not allowed to modify any part of the provided header files SSLColumn.h and SortedSquareList.h except to add additional helper function and data members in the section between the labels:

      // STUDENT-ADDED MEMBERS HERE
      ...
      ...
      // END STUDENT-ADDED MEMBERS
    

    We will be doing a strict check, and if there were any additions, deletions, or modifications to any other part of either of these files, you will receive a substantial deduction!

    Requirement: Do not use any global variables!

    Requirement: Your code must compile on GL with the exact Unix commands given below. (See "How to Submit".)

    Requirement: Your code must not have any memory leaks. When you run your code under valgrind on GL, it must report:

    All heap blocks were freed -- no leaks are possible This means you must be thorough with your destructor implementations.

    Requirement: Your implementation must be efficient. We will provide tests later that will validate the performance of your code meets the requirements set out earlier in this specification.

    Requirement: Many of the required functions described below throw exceptions. All of the exceptions we require are defined in stdexcept so all you need to do is

    #include <stdexcept>

    at the top of your source.
    You should not throw any other exception types outside your code; if you define your own exception classes, you must catch them and handle them completely inside your own functions.



    These are the member functions of the SSLColumn class you must provide, with the exact signatures:



    • SSLColumn(int n=2) ;

      This is the constructor for the SSLColumn class. It should initialize the data members and allocate memory to hold at least n int values. The member m_data should point to this memory. The default value of n is 2.



    • SSLColumn(const SSLColumn& other) ;

      This is the copy constructor for the SSLColumn class. The copy constructor must create a complete, exact copy of the SSLColumn object other. The new copy must have separately allocated memory for the circular buffer of int. By "exact copy", we mean that the circular buffer properties must be preserved: each and every circular buffer must duplicate data arrays element-for-element, and the start and end indices must be preserved. Do not use the assignment operator to implement the copy constructor. Just don't. No really, it's a bad idea.



    • ~SSLColumn() ;

      This is the destructor for the SSLColumn class. You must deallocate memory. You should (almost) never call a destructor explicitly.



    • const SSLColumn& operator=(const SSLColumn& rhs) ;

      This is the overloaded assignment operator. If you forgot what that means, crack open your C++ textbook again. Remember to check for self-assignment. The SSLColumn objects on the left hand side (LHS) and right hand side of the assignment (RHS) are not required to have the same capacity. Typically, you would gut the LHS object (deallocate and reallocate dynamic objects, etc.) and recreate it to make it an exact duplicate of the RHS. We will not do that here; ours is spiritually more like assigning across mixed numerical types. If your LHS SSHColumn has capacity equal to or greater than the RHS's active size, you should just transfer the active data. (This will allow us to resize our structures by creating a new empty larger one, then just doing an assignment to copy the data.) You do not have to preserve the positioning within the circular buffer, as you did with the copy constructor: you can just copy it starting at index 0 in the target array.

      If the LHS does not have to capacity to hold the active data of the RHS, you should then reallocate the dynamic data in the LHS to match the capacity of the RHS. Remember to deallocate space of the LHS object first.

      You can't use the copy constructor to implement the assignment operator. That would create a third object, which isn't what you want. Really, that doesn't work. If you don't "remember" why you have to check for self-assignment, then go read up on assignment operators. It will actually save you time.



    • void add(int data);

      This function should add the value in the data parameter to the column's circular buffer in the correct sorted position. Duplicates are allowed (meaning you don't have to check for them). This will require shifting items after the insertion point down one position. Remember to be aware of the wrap around. If the buffer is full, then throw an overflow_error exception. This exception is defined in stdexcept.
      This function must execute in O(n) time, where n is the number of items in the column.



    • void addFirst(int data);

      This function should add the value in the data parameter as the new first item in the column. The caller is responsible for ensuring the sort order is not violated. Remember to be aware of the wrap around. If the buffer is full, then throw an overflow_error exception. This exception is defined in stdexcept.
      This function must execute in O(1) time.



    • void addLast(int data);

      This function should add the value in the data parameter as the new last item in the column. The caller is responsible for ensuring the sort order is not violated. Remember to be aware of the wrap around. If the buffer is full, then throw an overflow_error exception. This exception is defined in stdexcept.
      This function must execute in O(1) time.



    • int find(int data);

      This function retrieves the index in the column of the value in the data parameter. The index is relative to the active part of the circular buffer, and is not the index in the underlying array. If the value was not found, return -1.
      This function must execute in O(log(n)) time, where n is the number of items in the column.



    • int findAt(int pos);

      This function retrieves the value at index pos in the column, retrieving the last item if pos == -1. The index is relative to the active part of the circular buffer, and is not the index in the underlying array. Other than the special "-1" case, if pos is outside the range of legal data positions, throw a range_error exception. This exception is defined in stdexcept.
      This function must execute in O(1) time.



    • int remove(int data);

      This function should remove the item in the column with the value specified by the data parameter. It should return the original position in the column where the item was found and deleted, or -1 if not found.
      This function must execute in O(n) time, where n is the number of items in the column.



    • int removeFirst(void);

      This function should remove first item in the column and return it. Remember to be aware of the wrap around. If the buffer is empty, then throw an underflow_error exception. This exception is defined in stdexcept.
      This function must execute in O(1) time.



    • int removeLast(void);

      This function should remove last item in the column and return it. Remember to be aware of the wrap around. If the buffer is empty, then throw an underflow_error exception. This exception is defined in stdexcept.
      This function must execute in O(1) time.



    • int capacity();

      This function should return the number of int values that can be stored in the amount of space allocated in the array of int that m_data points to. I.e., it's the length of the array of the circular buffer.



    • int size();

      Returns the number of items stored in the circular buffer.



    • void dump();

      This is a debugging function that prints out the contents of the SSLColumn object. See sample outputs below for suggested format. (You should follow the formatting as closely as possible, but don't worry about the exact spacing.)



    • bool inspect (int* &buf, int &cap, int &size, int &start, int &end);

      This function is used for grading. You do not need to implement anything for this function. In fact, it is important that you don't provide any code for this function, since the grading programs have their own implementations and your code won't compile if the compiler sees two implementations.



    These are the member functions of the SortedSquareList class:



    • SortedSquareList();

      This is the default constructor for the SortedSquareList class. It should initialize all of the data members and allocate space for a 2x2 (2 columns, each with room for 2 values) circular-buffer-of-circular-buffers. Note that m_cols is an array of pointers to SSLColumn instances. You need to initialize this array at construction time to already point to a full complement of constructed SSLColumn objects, each of the same size.



    • SortedSquareList(const SortedSquareList& other);

      This is the copy constructor for the SortedSquareList class. You have to make a complete, exact copy of the other object, down to the level of having the circular buffers identical in array content, start, and end points. Note that when we say "identical in array content", we are still requiring a deep copy--you should not just do a shallow copy of the m_cols array. Make good use of the SSLColumn copy constructor. The admonition to not use the SortedSquareList assignment operator to implement this copy constructor also holds here.



    • ~SortedSquareList();

      This is the destructor. You must deallocate space used by the SSLColumn objects that the array of pointers in m_buffers points to. Remember that you don't do that by calling the SSLColumn destructor explicitly, because you never call destructors explicitly.



    • const SortedSquareList& operator=(const SortedSquareList& rhs);

      This is the overloaded assignment operator for the SortedSquareList class. Read the reminders about assignment operators written in the specifications of the assignment operator for the SSLColumn class. They also apply here. So do the comments about what to do with size mismatches: in a nutshell, if the LHS is larger than the RHS, just transfer the data, but if the LHS is smaller (specifically, LHS's capacity < RHS's size), you must reallocate everything in the LHS to match the size of the RHS, and then copy.



    • void add(int data);

      This member function adds the value in the data parameter to the square list, in sorted position. The code for this function (and for remove()) are responsible for keeping the square list "square": a detailed description of the exact process is given above. Unless you are at the full capacity of this data structure, this function should not require allocating any actual SSLColumn objects: all of those should have been constructed when this SortedSquareList object itself was created. However, the rebalancing process might cause this function to shift data into an existing-but-unused SSLColumn by extending the head or tail of the top-level circular queue of SSLColumn objects managed by this class. In other words, you do not allocate the SSLColumn, you just start using one that was dormant (i.e., not previously in the active part of the circular buffer).

      Before actually inserting the new value, this function must first test to see if the existing data structures are at capacity, and if so, it must grow the square list, as described earlier. The rebalancing process is designed to never try to grow beyond the actually allocated number of columns until every column is completely full, and conversely, it will never ask to grow a column beyond its maximum size until every column has been filled, so a simple comparison of size to capacity for the square list is all that is required.

      Resizing will require allocating a new larger top-level circular buffer, creating all-new SSLColumn objects (more, and larger) to fill it, then copying the old SSLColumns' data into some of the new SSLColumns (the rest of the new columns are again for future expansion), then deleting all of the old SSLColumns, and finally deleting the old top-level circular buffer from this square list.



    • int find(int data);

      This function retrieves the index in the list of the value in the data parameter. The index is relative to the sorted order of all the data stored in the entire square list, and does not have any relationship to to where it is actually stored. If the value was not found, return -1.
      This function must execute in O(log(n)) time.



    • int findAt(int pos);

      This function retrieves the value at index pos in the list, in sorted order, retrieving the last item if pos == -1. Other than the special "-1" case, if pos is outside the range of legal data positions, throw a range_error exception. This exception is defined in stdexcept.
      This function must execute in O(log(n)) time.



    • bool remove(int data);

      This function should remove the item in the list with the value specified by the data parameter. It should return true if the item was successfully found and deleted, or false if not found.
      This function must execute in O(sqrt(n)) time.



    • int size();

      Returns the number of values currently being stored in the data structure.



    • void dump();

      As before, this is a debugging function that prints out the contents of the entire data structure. Make good use of SSLColumn::dump(). See sample output below for suggested format.



    • bool inspect (SSLColumn** &buf, int &cap, int &size, int &start, int &end);

      As with SSLColumn::inspect(), this function is used for grading. Just don't do anything with this function, you will be fine.


    Test Programs

    The following test programs are provided to jump-start your imagination on how you should test your programs. They are illustrative, but in no way exhaustive. In the future, we will provide less hand-holding for the testing phase of your projects; you should be able to imagine where the potentially buggy edge cases are, and write your own test programs to exercise that code. This is a big part of what you will be doing in the real world.

    Three very important things about the set of programs we are providing:

    1. These are not the programs we will be using to grade your projects;
    2. The test programs do not test all possible scenarios; it will not be in any way an acceptable excuse for broken functionality in grading, to say: "...but it worked for all the test programs you gave us!"
    3. Already for this first project, and even more so for all following projects, you might not get the exact same results as what we show in our sample output. If you do get the same results, that's good. However, if you get slightly different results, it is your responsibility to determine whether your program really needs fixing, or it is just a reasonable variation in interpretation.

    Note that if your program does not successfully compile without errors or warnings, or if it dies with a segfault or other such unexpected error, it is highly likely to not pass our grading tests, either. To put it in math terms, passing our tests is a necessary, but not sufficient, condition.

    These files are also available on GL in the directory:

    /afs/umbc.edu/users/p/a/park/pub/cs341/00Proj1/


    Implementation Notes

    • Be careful about how you implement find-by-index (as opposed to by-value). Even if you can determine in O(log(n)) time the position within the particular column the value is stored in, if it takes you O(sqrt(n)) to determine where that column starts in the overall ordering of all data (for example, by adding up the sizes of the columns before it), the runtime will be O(sqrt(n)), exceeding the required O(log(n)) time.
    • Remember to wrap around when indices go past the end of the array.
    • Don't confuse size and capacity. The size is the number of items stored in the circular buffer. The capacity is how much space was allocated.

    How to Submit

    You must submit the following files to the proj1 directory.

    • SSLColumn.h
    • SSLColumn.cpp
    • SortedSquareList.h
    • SortedSquareList.cpp

    Even if you ended up not adding any new members toSSLColumn.h or SortedSquareList.h you should still submit them. You must have still edited them to remove the placeholder lines with "...".

    For this project (and definitely for future projects), it is probably best for you to do the primary development in some directory other than the submit directory. That way, you can create all manner of other files (other test programs, reminders to yourself, etc.) that you obviously do not want to submit. Let us say you initially developed your files in the directory "~/work/cs341/p1" (this is completely made up; you can organize your work directories any way you want). If you followed the instructions in the Project Submission page to set up your directories, you can submit your code using this Unix command from the directory you have been working in:

    linux1% cp SSLColumn.h SSLColumn.cpp SortedSquareList.h SortedSquareList.cpp ~/cs341proj/proj1/

    Use the Unix script command to show that your code compiles:

    linux1% cd ~/cs341proj/proj1/ linux1% cp ../../00Proj1/p1test*.cpp . linux1% script Script started, file is typescript linux1% g++ p1test01.cpp SSLColumn.cpp -o t01.out linux1% g++ p1test02.cpp SSLColumn.cpp -o t02.out linux1% g++ p1test03.cpp SSLColumn.cpp -o t03.out linux1% g++ p1test06.cpp SSLColumn.cpp SortedSquareList.cpp -o t06.out linux1% g++ p1test07.cpp SSLColumn.cpp SortedSquareList.cpp -o t07.out linux1% g++ p1test08.cpp SSLColumn.cpp SortedSquareList.cpp -o t08.out linux1% g++ p1testXX.cpp SSLColumn.cpp SortedSquareList.cpp -o tXX.out [COMPILATION OF ALL TESTS] linux1% exit exit Script done, file is typescript

    Do remember to exit from the script command. This creates a file called typescript that will record any compilation errors. Yes, we know you can edit this file, but the compilation errors will just show up when we compile the programs again and you will still get lots of points deducted. This step is to compel you to fix any changes needed to get your program to compile on GL without any errors.

    Note: cd to the appropriate directory if you are submitting late.

    Run t01.out thru t10.out under valgrind:

    linux1% valgrind ./t01.out ... linux1% valgrind ./t02.out ... linux1% valgrind ./t10.out

    If you do not see

    All heap blocks were freed -- no leaks are possible

    after each run, then you have a memory leak. You are not ready to submit. Go back and fix your program. If valgrind reports other memory errors (e.g., reading from invalid memory or writing to invalid memory) then you don't have a memory leak, but you have some other sort of bug. You should also go back and fix your program.

    Now you can delete the executable files with

    rm t??.out

    Then you should just have 5 files in your submission directory. Check using the ls command. You can also double check that you are in the correct directory using the pwd command. (You should see your username instead of xxxxx.)

    linux1% ls SortedSquareList.cpp SortedSquareList.h SSLColumn.cpp SSLColumn.h typescript linux1% pwd /afs/umbc.edu/users/c/h/chang/pub/cs341/xxxxx/proj1 linux1%