Title image Spring 2018

Due: Wednesday 15 February 2018

Part I: C Programming

For this part of the project, you will write a few simple C programs to experiment with data types, memory access, arrays, and memory management. The intention is to break stuff, so have fun.


Please use the command line on a terminal/xterm to compile and run your programs. You can use the Terminal program, or start up X-windows by typing xterm in a Terminal window.

You may use whatever editor you want. I recommend learning TextWrangler, emacs, or XCode, although some folks like Eclipse.

For all of these C programs, your code should have the following form.

 * A short description of the program
 * Your Name
 * Date 

#include <stdio.h>
#include <stdlib.h>

/* A short description of the function, if necessary
int main (int arg, char *argv[]) {
  // your stuff here	
  return 0;

To compile a C program, use gcc. The -o option lets you specify the name of the executable. To run your executable, type its name on the command line. You may need to put a ./ in front of the name to tell the shell to look in the current directory for the executable.

$ gcc -o myexec mycfile.c
$ ./myexec

  1. Memory access: write a program that declares a variable of each of the basic types (char, short, int, long, float, double) and assigns each one a value (your choice). Declare an unsigned char * and then go through each data type and look how it is stored in memory. You may want to use the sizeof function to control the for loop. Calling sizeof(double), for example, returns the number of bytes used for a double.

    You can do this by first taking the address of each variable, casting it to an unsigned char *, and assigning it to your unsigned char * variable. For example:

      int q = 0x01234567;
      unsigned char *ptr;
      ptr = (unsigned char *)&(q);

    Then you can loop through the char pointer, treating it as an array and print out each byte. The function sizeof returns the number of bytes in a data type. Continuing the example above, you can use printf with the format string "%02X" to print out each byte of the int.

    for(i=0;i<sizeof(int);i++) {
        printf("%d: %02X\n", i, ptr[i]);

    Note how the data is stored in memory. Is the machine you are using a big-endian or little-endian machine? How does this program tell you? Look up the definition of big-endian and little-endian to support your answer.

  2. Make a program that declares and assigns some variables. Have the last variable you declare be an unsigned char *.

    Give the unsigned char * the address of itself. Then write a for loop that prints out and accesses memory in sequence using the unsigned char * from index zero onwards with no stopping condition (ok, start by printing out only the first 100 bytes or so). The only statement in the for loop should be a print statement showing the current index and the byte currently accessed by the unsigned char *. Be sure to put a newline at the end of the print format string so the information is flushed to the screen (try it without a newline and see the difference).

    Run the program and see how much memory you can access. What happens at the end of the process? Can you see the other variables you declared?

  3. Write a program that repeatedly allocates a small amount of memory in a loop that goes on for a long time. Use just a single variable to point to the memory (this is very bad, but it makes a good example). Using the terminal command top (or, if you are on a Mac, you can use the Activity Monitor), watch the memory requirements for your program grow.

    Now add a free statement to the loop that frees the memory you just created. Then watch your memory requirements using top. What is the difference?

  4. Make a struct that has 3-4 different variables (including some char and short types). Set up the struct so it should use an odd number of bytes.

    Write a program that allocates one of these structs. Then use the unsigned char * to look at how the memory is laid out. Does the sizeof result match your expectation? Are there any gaps in the way the fields of the structure are laid out?

  5. Demonstrate how, by passing a string that is slightly too long to a function, you can overwrite a decision variable within the function if the function uses strcpy (and don't forget to include string.h) to copy the parameter to a local character array of fixed length. Make it a clear demonstration by having the function print out safe if the decision variable has the value 0 and hacked if the decision variable is non-zero. If the program crashes instead of printing hacked, that is a perfectly fine demonstration.

    If you really want to make it work, try making a struct with a fixed size string and an int inside the struct. Then overwrite the end of the string and see if it affects the value of the int.

Part II: Selected Langauges

In this part of the project, select four languages other than C that you do not know. Look at the Languages page and pick at least one from each list (A, B, and C).


Do some research regarding the four languages. For each one, write a paragraph to describe it in terms of:

  1. the purposes for which the language was designed,
  2. the main uses for the language,
  3. when the language was developed,
  4. whether it is a compiled or interpreted language, and
  5. whether it is open source or proprietary.


The following are some suggested extensions. You may also choose your own extensions of interest related to the project topic.

  1. Write the shortest C program you can to generate a bus error. What is the difference with a seg fault?
  2. Find the floating point number in C to which you can add one and get back the same number.
  3. Make the safe/hacked C program use a string from the command line.
  4. What other kinds of run-time errors can you generate with very simple C programs?
  5. Do some research regarding a fifth language and write a paragraph for it.


Your project submission should have three components:

  1. C code: The C code for each task should be submitted to the fileserver. Put each project in its own directory inside your Private handin folder. Each task should have a separate C file, and the filename should specify the task name (e.g., task1.c). Note that the quality of your comments counts toward your grade. In addition to the top-level comments, block-level comments help readers to understand your code.
  2. README: For each project you must submit a README file along with your C code. The README file can be a .txt file. It should contain the following information.
    • Project identifier, your name, and the submission date.
    • The directory layout for your handin folder. You can use the Unix tree command to generate this.
    • Your operating system and C compiler (e.g. use gcc --version).
    • For each task, the compile, usage, known bugs, and expected output of each program. You should not include the actual output of running the program unless it is short, just a description of what the output means. This should include both your C programs and programs written in other languages.
    • Your answers to any questions in the C tasks.

    You can use this README template.

  3. Wiki Report: your wiki report should have the following elements.
    • Title of the project and your name
    • A brief introduction to the languages you selected
    • At least four paragraphs, with a header for each, to describe the four selected languages

Please note that it is your responsibility to explicitly indicate any extensions you have completed. If you undertake any of the C extensions, please indicate them in your code and the README file. If you undertake extensions in one of your selected languages, please indicate this in your wiki report.