COMP2004 Programming Practice
2002 Summer School

Week 2 Wednesday Tutorial Exercises


  1. Assignment 0 is due at the end of today's lab, so if you haven't already done it, this is your last chance. It's better to make a silly mistake on Assignment 0 (and learn from that for Assignment 1), than to make a silly mistake on Assignment 1 where it might cost you marks.

  2. Here's some code that shows some of the things that can go wrong with stack based memory. Try and understand why it outputs what it does, and add some extra variables and see what happens.

  3. Here's some code that shows some of the things that can go wrong with heap based memory. Do as above.

  4. Rewrite the join function from Question 6 of the Week 1 Friday tute using arrays of std::string objects instead of std::vector<std::string>. For example, instead of
    std::vector<std::string> vs;
    vs.push_back("hello"); vs.push_back("how"); vs.push_back("are");
    std::string j = "fred";
    std::cout << join(j,vs) << endl;
    
    use
    const int n = 3;
    std::string as[n] = {"hello", "how", "are"};
    std::string j = "fred";
    std::cout << join(j,as,n) << endl;
    

  5. Rewrite the split function from Question 7 of the Week 1 Friday tute using arrays of std::string objects instead of std::vector<std::string>, as above.

  6. Rewrite the getDigits function from Question 12 of the Week 1 Friday tute using arrays of unsigned ints instead of std::vector<unsigned int>. ie. the getDigits() function should now look like
    unsigned int* getDigits(size_t &n, unsigned long number)
    
    You should also have getDigits() allocate memory with "new" for the array of digits which is returned by getDigits(). The number of digits (and therefore the number of elements in the array) should be "returned" by setting the value of n which is passed by reference.

  7. Write a function which converts the argc and argv arguments to main() into a vector of strings. ie. the function should look like
    void convert_args(std::vector<std::string> &v, int argc, char** argv)
    
    You could then use this function like this
    int main(int argc, char** argv) {
    	std::vector<std::string> args;
    	convert_args(args, argc, argv);
    	for (int i = 0; i < args.size(); ++i) {
    		std::cout << args[i] << std::endl;
    	}
    }
    
    In case you're wondering, the vector of strings is passed by reference and not simply returned because returning the vector would require it to be copied, which is inefficient.

  8. This program implements a menu system using a function for each menu entry, and a switch statement to run each of the functions depending on the user's input. It should be fairly easy to understand. However, the code can be made much more elegant if the switch statement is replaced with an array of function pointers to each of the various functions, and then indexing into that array based on the user's input.

    Convert the program so that it works in this way. You might find the following typedef useful

    typedef void (*menu_function)(void);
    
    which defines the type menu_function to be a pointer to a function with no parameters and no return value.

    (Note that the functions menu_item_0(), menu_item_1(), etc should be left alone. Although they are repetitive, in a real menu system each one would do a different task.)

  9. This program shows the effect of leaking memory. It loops 15 times, each time allocating 1Mb of memory and then pausing for 1 second.

    First, open a new xterm window. In it, run the command

    top
    
    Press u, type in your login name, and press Enter.
    Press o (the lowercase letter o, not the number 0), type in size, and press Enter.
    Press s, type in 1 (the number one), and press Enter.

    The top program will now be showing you all of the programs you have running on the system, sorted by how large they are in memory, and updated every second.

    Compile and run the leaky program. As it runs, you should be able to see its "size" in top increase by about 1Mb (1000Kb) every second.

    Now modify the program so that after sleeping, the memory allocated is deallocated. Recompile and rerun the program. You should be able to see in top that the size of the program stays constant as it runs.