Due: Wednesday, February 19 2025, 11:59 pm

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 learn how variables are laid out in the stack, and you will be writing a report with drawings of the stack.

You need to install a C compiler to program in the C language. Most macOS and Linux machines have a C compiler shipped with it. A way to check whether your machine has a C compiler is to open a terminal and type gcc --version. If you don't get any message indicating that the command gcc doesn't exist, your machine should have the compiler already. You probably need to install a C compiler if you use a Windows machine. If so, you can start with Cygwin, a Linux emulator for Windows which gives you a flavor of Linux and enable you to install a C compiler easily. If you have Visual Studio, you can install the components you need for building C apps. If you don't want to bother with installation, you can use the machines in the robotics lab (Davis 122), Davis 101, and Davis 102. The machines in the CS department have a C compiler installed already. You can remotely access the machines in the robotics lab. E.g., if you'd like to access fili (the name of a computer in Davis 122), you can use ssh yourColbyAccount@fili.cs.colby.edu.

Tasks

Please use the command line on a terminal to compile and run your programs.

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

Implement each task in an individual C file. 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 i = 0x01234567;
    unsigned char *ptr;
    
    ptr = (unsigned char *)&(i);
    

    Then you can loop through the char pointer, treating it as an array. 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]);
    }
    

    Report: Show your output and use it to explain how you can determine whether your machine is big- or little-endian.

    1. Take a screenshot of the output and include it in your report.
    2. Is the machine you are using a big-endian or little-endian machine?
    3. How does the program output tell you?
    Look up the definition of big-endian and little-endian to support your answer.

  2. Make another program that allows you to see where values are on the stack. Declare 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 appropriately (try it without a newline and see the difference).

    Report: Your goal for the report is to interpret the output of your program..

    1. Include a screenshot of your output.
    2. What seems to be the overall layout of the stack?
    3. Are there any non-zero values you can't immediately make sense of?
    4. Can you find the variables defined in your C program? Highlight the ones you find and explain how you know you have found them.

  3. Write a new program that repeatedly allocates a small amount of memory in a loop that goes on for a long time. Just use 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.

    Report: Your goal is to describe memory being hogged or not.

    1. Include a screenshot of your memory usage (e.g. Activity Monitor or Top).
    2. briefly describe the memory requirements when using and not using the free statement.

  4. Make a struct that has 3-4 different variables (including some char and short types). Set up the struct so that the minimal number of bytes it would require to construct is odd.

    Write a program that allocates memory for the struct. Then use the unsigned char * to look at how the memory is laid out.

    Your goal is to understand how the compiler choses to lay out the variables. To do that, you will need to try multiple options (at least 3). E.g. if you have a single char before and after an int, is that different from having two chars before the int?

    Report: Your goal is to explain how various versions of the struct are laid out in memory. Answer these questions and use them as a guide for your overall layout. Include drawings of all of your layouts.

    1. Does the sizeof result match your expectation?
    2. Are there any gaps in the way the fields of the structure are laid out?

  5. Check out this silly BankExample code. It starts by reading in a given user's name as a string, saves it into a string field of a struct, then prints out some info regarding the new account that has been created. Here's an example run through:

    However, there's a problem for various inputs:

    Presumably, the bank wouldn't want us to write code for them that could be abused in this way.
    1. First, find a string that doesn't work. Run the program on it and show that it starts with a positive balance on your given input.
    2. Next, use an unsigned char * to identify what the memory contents look like on your bad string.
    Report:
    1. What is the string you found that doesn't work?
    2. Include a screenshot of the memory contents on your bad string.
    3. Explain in detail what has gone wrong and why.

Part II: Selected Languages

In this part of the project, you are expected to select four languages other than C that you do not know. Look at the Programming Languages section in the Course Outline page and pick one from each list (A, B, and C).

Tasks

Do some research regarding the four languages. For each of them, you will have a paragraph on your Google Sites report to describe it in terms of:

  1. the design purposes of the language,
  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.

Extensions

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 from 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 task 5 in Part I more robust (e.g., the inputs won't impact the initial balance).
  4. What other kinds of run-time errors can you generate with very simple C programs?
  5. Do some research regarding a fifth language. Have a paragraph of description for it on your written report (on Google Sites).

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

Submission

The submission of this project is in two components:

  1. Create a folder for Project1_<username> (e,g. for Stephanie Taylor, this would be Project1_srtaylor). Place the required files into it, zip it, and upload it to the Google Classroom.

    Required Files:

    1. Code: Each task should have a 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: We use markdown files for README files. Markdown files are files with the .md filename extension. Each project should have a README file along with all your source codes. The README file will contain:
      • Project identifier, your name, and the submission date.
      • The URL of your Google Sites report.
      • The directory layout for your hand-in 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, include how to compile your program, how to run your program, known bugs if there is any, and the program output (a screenshot). The screenshot should include the actual output of running the program if the output is no more than 100 lines. Otherwise, give a brief version of the output.
      • Text and images reporting on the C part of the project.
      • A description of each extension you undertook (for the C part of the project).

      You can use this README template. If you are new to markdown files, this tutorial can help you get started. You can use any text editors for markdown files. If you want to use Visual Studio, here is a helpful doc.

  2. Google Sites Report: The report of this project should have the following elements.
    • A home page for your CS333 projects. The home page should have a title (e.g., Ying's CS333).
    • A subpage under the home page that should include:
      • Title of the project (e.g., Project 1)
      • A brief introduction to each languages you selected
      • One section per language that contains a logo of the language and a brief introduction answering the five questions listed in Part II.

    This sample home page and project 1 page are for your reference. You don't need to worry about the JS and R sections on the home page. They are for the following projects. Please log in to Google Sites using your Colby account before clicking the links.

    Here is an instruction for you to quickly start using Google Sites for CS333. Please log in to Google Sites using your Colby account before clicking the links. You can also find other resources on the Internet if you want to know more about Google Sites.

© 2025 Ying Li, Stephanie Taylor, Max Bender. Page last modified: .