Remember to create a new directory in your repository for this lab. (Refer to previous labs for how if you have forgotten)
You have two tasks to complete before your lab. First, refer to your notes about string functions, , command-line arguments, pointers, and structs, and answer the questions in lab5questions.html.
Second, read through the warmup exercises so you are ready to begin in class.Up until now, your program has executed all of the tests in a single run. This is fine when all goes well. However, if one of your tests experiences a segmentation fault, then the program ends, and further tests will not execute. This is not ideal.
Instead, each test should be a separate execution of the program. Then, you string together the tests with a script. This script contains the command line for each test. If one fails, that's fine, it then proceeds to the next test. Therefore, you need a file you didn't need before: the script.
The command-line arguments provide all information to know which test to execute and provide any input arguments it needs. If you missed the lecture on command-line arguments, you can read an on-line tutorial.
For example, let's take the exercises you are going to be completing for the
string warm-up. We can assign a letter to each one of them, shown below:
0) Safe_str_concat
1) write_value
2) read_value
2) Create and initialize a heightxwidth image, write to filename.
To use this program, you would do the following:
This would result in:./warmup5 1 firststring secondstring
Likewise,firststringsecondstring
This would result in running a pre-set sequence of tests you wrote for exercise 2./warmup5 2 1
This would result in running a different pre-set sequence of tests you wrote for exercise 2 Likewise,./warmup5 2 2
would create an image that is 200x500, with each pixel being (128, 0, 128)../warmup5 3 200 500 128 0 128 test200x500rb.png
Once you have made testscript, you need to make it executable: chmod +x testscript../warmup5 3 100 50 0 128 128 test100x50gb.png ./warmup5 3 200 500 128 0 128 test200x500rb.png
During the warmup, you are going to implement several functions that exercise strings, pointers, and structs.
Create the skeleton code. This is NOT given to you. You need to fill it in.
warmup5.h,
warmup5.c,
warmup5_main.c, and
testscript.
char *safe_str_concat(char *str1, char *str2);
In the normal string concatenation function, the second string is copied to the end of the first string - and it's not known whether there was enough space to do so. This is the source of bugs in systems that have allowed attackers to gain control of the system.
Write a function that, instead of copying str2 to the end of str1, allocates a brand new string that will hold both str1 and str2. Then it copies both strings over, str1 at the front and str2 at the back. It returns a pointer to that new string.
typedef struct { unsigned int allocated_size; int *array; } int_vector; int_vector* make_init_array(); void write_value(int_vector *vector, unsigned int index, int value); int read_value(int_vector *vector, unsigned int index);
Arrays are hard to work with in C for two reasons. First, the size is passed around separately from the array itself. Second, there is no check to make sure you are accessing within the array.
In this problem, you create a new data type - an array that carries around the size with it. A struct contains the necessary information. A programmer first requests a new array with make_init_array, which allocates the int_vector and initializes the values for an array with 0 items. The programmer then accesses it through function calls (very inefficient - just an educational exercise). If an index beyond the end of the array is used, then the array is reallocated. The new array needs to be the maximum of big enough to hold the index requested and double the current size of the array (with minimum being 16). Malloc the bigger array, copy over any elements that were already in the array, free the old array, update the size, and hook the structure to the new array. If the programmer reads an element of the array beyond the length, return 0 but don't expand the size of the array.
Reminder: As I announced in class, you are not allowed to use realloc. You may only use malloc to allocate space.
typedef struct { unsigned int red; unsigned int green; unsigned int blue; } pixel; pixel** make_and_init_image(int height, int width, pixel color);
Write a function that creates a double array of pixels. It consists of an array of length height, and each element of that array points to an array of length width. The array of length width is an array of pixels. Each pixel is initialized to color. Make sure you put the struct definition in the .h file ONLY - not also the .c file.
I have now provided the png files to go along with this assignment. You can use warmup5_provided.h, warmup5_provided.c, uchicago.png
If you inspect these files, you will see that we have provided the read and write to png files. For this exercise, you need only the write function. This represents two changes. First, it uses the pixel data structure. Second, it uses malloc, removing the restrictively small size limitation. You can now use it on much larger pictures.
One note: The pixel struct is declared in warmup5_provided.h. This means you do NOT need to place it in your own warmup5.h file. You cannot put it twice. That means you need to #include the warmup5_provided.h file before the warmup5.h file.