forked from YurieCo/CSE351-2
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5fd9e72
commit c7f2113
Showing
172 changed files
with
121,294 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// Chun-Wei Chen | ||
// CSE 351 | ||
// 04/03/13 | ||
|
||
// These #includes tell the compiler to include the named | ||
// header files, similar to imports in Java. The code for | ||
// these is generally located under /usr/include/, such | ||
// as /usr/include/assert.h. assert.h contains the | ||
// declaration of the assert() function, stdio.h contains | ||
// the declaration of the printf() function, and stdlib.h | ||
// contains the declaration of the malloc() and free() | ||
// functions, all of which are used in the code below. | ||
#include <assert.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
// Fill the given array with values. Note that C doesn't | ||
// keep track of the length of arrays, so we have to | ||
// specify it explictly here. | ||
void fillArray(int* array, int len) { | ||
printf("Filling an array at address %p with %d " | ||
"values\n", array, len); | ||
for (int i = 0; i < len; ++i) { | ||
array[i] = i * 3 + 2; | ||
// assert() verifies that the given condition is true | ||
// and exits the program otherwise. This is just a | ||
// "sanity check" to make sure that the line of code | ||
// above is doing what we intend. | ||
assert(array[i] == i * 3 + 2); | ||
} | ||
printf("Done!\n"); | ||
} | ||
|
||
// Structs are simply storage for memory of various types. | ||
// In this case, we are typedef-ing (as in naming) a | ||
// struct containing four integers as FourInts. | ||
typedef struct { | ||
int a, b, c, d; | ||
} FourInts; | ||
|
||
// main() is the entry point of the program. | ||
int main(int argc, char* argv[]) { | ||
// Create a new array capable of storing 10 elements | ||
// and fill it with values using the function declared | ||
// above. Arrays declared in this manner are located on | ||
// the stack, which is where statically allocated (as | ||
// in not at runtime) memory is stored. | ||
int array[10]; | ||
// The "array" that we pass here is actually a pointer | ||
// to a block of memory capable of storing 10 integers. | ||
// array[0] is the first integer in this block of | ||
// memory, array[1] is the second, and so on. Since | ||
// C does not track array lengths, we have to specify | ||
// how many elements the array contains. | ||
// | ||
// TODO(1): What happens if the second argument is set | ||
// to 11 instead? How about 100? 1000? Make sure to set | ||
// the second argument back to 10 when you are done | ||
// testing. | ||
// Answer: Setting the second argument to 11 doesn't give | ||
// segementaion fault. It just accesses another part of the | ||
// already allocated stack space. Setting the second argument | ||
// to 100 or 1000 gives segementaion fault since it has now | ||
// accessed beyond the part of memory that is allocated for the stack. | ||
fillArray(array, 10); | ||
|
||
int value; | ||
// In C, we can take the address of something using the | ||
// & operator. &value is of the type int*, meaning that | ||
// it is a pointer to an integer (as in it stores the | ||
// address in memory of where the actual int is located). | ||
// | ||
// TODO(2): We can actually use the address of the value | ||
// declared here as if it were an array of a single | ||
// element; why is this possible? | ||
// Answer: Since &value is of the type int* and the first | ||
// argument of fillArray also takes an int*, it works fine. | ||
fillArray(&value, 1); | ||
// fillArray should set value to 0 * 3 + 2 = 2. | ||
assert(value == 2); | ||
|
||
// The following creates an instance of FourInts on the | ||
// stack. FourInts is really just an array of four ints, | ||
// although we can refer to the ints stored in it by | ||
// name as well. | ||
FourInts four_ints; | ||
// Set the first int to have a value of 0 and verify | ||
// that the value changed. | ||
four_ints.a = 0; | ||
assert(four_ints.a == 0); | ||
|
||
// Depending on whether or not you like to live | ||
// dangerously, the following is either exciting or | ||
// terrifying. Though &four_ints is of type FourInts* | ||
// (as in a pointer to a FourInts struct), we can | ||
// use a cast to pretend that it is actually an array | ||
// of integers instead. | ||
fillArray((int*) &four_ints, 4); | ||
// We can confirm that fillArray updated the values | ||
// in the FourInts struct: | ||
assert(four_ints.a == 2); | ||
assert(four_ints.b == 5); | ||
assert(four_ints.c == 8); | ||
assert(four_ints.d == 11); | ||
|
||
// In the case that the size of an array is not known | ||
// until runtime, the malloc() function can be used to | ||
// allocate memory dynamically. Memory that is | ||
// allocated dynamically is stored on the heap, which | ||
// is separate from the stack. C is unlike Java, | ||
// however, in that dynamically-allocated memory must | ||
// be freed explicitly when the program is done using | ||
// it via the free() function. malloc() takes a single | ||
// argument, which is the number of bytes to allocate. | ||
// sizeof(int) gives how many bytes an int contains | ||
// (which is four), so sizeof(int) * 5 is 20. | ||
int* heap_array = (int*) malloc(sizeof(int) * 5); | ||
fillArray(heap_array, 5); | ||
// Now that we have finished with the heap-allocated | ||
// array, free() the memory associated with it. | ||
// | ||
// TODO(3): What happens if we remove the free() | ||
// statement below? Try running "valgrind ./arrays" | ||
// after compiling the program both with and without | ||
// it. valgrind is a tool for analyzing how programs | ||
// use memory, which is often invaluable for C and | ||
// C++ programming. | ||
// Answer: Memory leak occurs. When I ran "valgrind ./arrays" | ||
// it shows 20 bytes in 1 blocks are definitely lost. | ||
free(heap_array); | ||
|
||
// TODO(4): Now it's your turn to write some code. | ||
// Using malloc(), allocate a FourInts struct | ||
// dynamically (on the heap) and use fillArray to | ||
// populate it with values. Make sure to free the | ||
// memory when you are done, and use the valgrind | ||
// tool mentioned above to check that there aren't | ||
// any errors. As a "sanity check," add four assert | ||
// statements to verify that the a, b, c, and d | ||
// fields of the FourInts struct are set to what | ||
// you would expect. (Hint, you'll need to use the | ||
// -> operator to access fields of a FourInts* | ||
// variable instead of the . operator). | ||
FourInts* fourInts = (FourInts*) malloc(sizeof(int) * 4); | ||
fillArray((int*) fourInts, 4); | ||
assert(fourInts->a == 2); | ||
assert(fourInts->b == 5); | ||
assert(fourInts->c == 8); | ||
assert(fourInts->d == 11); | ||
free(fourInts); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
TODO(1): What happens if the second argument is set to 11 | ||
instead? How about | ||
100? 1000? Make sure to set the | ||
second argument back to 10 when you are done | ||
testing. | ||
|
||
Even if the second argument is too large (i.e. larger | ||
than the array really is), fillArray will write that | ||
many integers to memory, overwriting whatever exists | ||
beyond the bounds of the array. If the second argument | ||
is very | ||
large, it may cause a segfault. | ||
|
||
|
||
TODO(2): We can actually use the address of the value declared | ||
here as if it were an array of a single element; | ||
why is this possible? | ||
|
||
An array in C is just a sequence of pointers to | ||
locations in memory, so in a | ||
very real sense, this | ||
value IS an array of a single element. | ||
|
||
TODO(3): What happens if we remove the free() statement below? | ||
|
||
|
||
The memory will never be freed, resulting in a memory | ||
leak - an area of memory | ||
which has already been | ||
allocated, but cannot be accessed by the running code. | ||
Particularly bad or persistent memory leaks can lead | ||
to a program running out of | ||
memory entirely, so it's | ||
important to avoid this situation by freeing all | ||
the memory you malloc. | ||
Your code for TODO(4) should look something like this: | ||
|
||
|
||
FourInts * ints = (FourInts *) malloc(sizeof(FourInts)); | ||
fillArray((int *) ints, 4); | ||
assert(ints->a == 2); | ||
assert(ints->b == 5); | ||
assert(ints->c == 8); | ||
assert(ints->d == 11); | ||
free(ints); |
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# | ||
# Makefile that builds btest and other helper programs for the CS:APP data lab | ||
# | ||
CC = gcc | ||
CFLAGS = -O -Wall -m64 -g | ||
LIBS = -lm | ||
|
||
all: btest fshow ishow ptest | ||
|
||
btest: btest.c bits.c decl.c tests.c btest.h bits.h | ||
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c | ||
|
||
fshow: fshow.c | ||
$(CC) $(CFLAGS) -o fshow fshow.c | ||
|
||
ishow: ishow.c | ||
$(CC) $(CFLAGS) -o ishow ishow.c | ||
|
||
ptest: ptest.c pointer.c | ||
$(CC) $(CFLAGS) -Wno-unused-variable -o ptest ptest.c pointer.c | ||
|
||
# Forces a recompile. Used by the driver program. | ||
btestexplicit: | ||
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c | ||
|
||
clean: | ||
rm -f *.o btest fshow ishow ptest *~ | ||
|
||
test: btest ptest | ||
./btest | ||
./ptest | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
*********************** | ||
The CS:APP Data Lab | ||
Directions to Students | ||
*********************** | ||
|
||
Your goal is to modify your copy of bits.c so that it passes all the | ||
tests in btest without violating any of the coding guidelines. | ||
|
||
|
||
********* | ||
0. Files: | ||
********* | ||
|
||
Makefile - Makes btest, fshow, and ishow | ||
README - This file | ||
bits.c - The file you will be modifying and handing in | ||
bits.h - Header file | ||
btest.c - The main btest program | ||
btest.h - Used to build btest | ||
decl.c - Used to build btest | ||
tests.c - Used to build btest | ||
tests-header.c- Used to build btest | ||
dlc* - Rule checking compiler binary (data lab compiler) | ||
driver.pl* - Driver program that uses btest and dlc to autograde bits.c | ||
fshow.c - Utility for examining floating-point representations | ||
ishow.c - Utility for examining integer representations | ||
|
||
*********************************************************** | ||
1. Modifying bits.c and checking it for compliance with dlc | ||
*********************************************************** | ||
|
||
IMPORTANT: Carefully read the instructions in the bits.c file before | ||
you start. These give the coding rules that you will need to follow if | ||
you want full credit. | ||
|
||
Use the dlc compiler (./dlc) to automatically check your version of | ||
bits.c for compliance with the coding guidelines: | ||
|
||
unix> ./dlc bits.c | ||
|
||
dlc returns silently if there are no problems with your code. | ||
Otherwise it prints messages that flag any problems. Running dlc with | ||
the -e switch: | ||
|
||
unix> ./dlc -e bits.c | ||
|
||
causes dlc to print counts of the number of operators used by each function. | ||
|
||
Once you have a legal solution, you can test it for correctness using | ||
the ./btest program. | ||
|
||
********************* | ||
2. Testing with btest | ||
********************* | ||
|
||
The Makefile in this directory compiles your version of bits.c with | ||
additional code to create a program (or test harness) named btest. | ||
|
||
To compile and run the btest program, type: | ||
|
||
unix> make btest | ||
unix> ./btest [optional cmd line args] | ||
|
||
You will need to recompile btest each time you change your bits.c | ||
program. When moving from one platform to another, you will want to | ||
get rid of the old version of btest and generate a new one. Use the | ||
commands: | ||
|
||
unix> make clean | ||
unix> make btest | ||
|
||
Btest tests your code for correctness by running millions of test | ||
cases on each function. It tests wide swaths around well known corner | ||
cases such as Tmin and zero for integer puzzles, and zero, inf, and | ||
the boundary between denormalized and normalized numbers for floating | ||
point puzzles. When btest detects an error in one of your functions, | ||
it prints out the test that failed, the incorrect result, and the | ||
expected result, and then terminates the testing for that function. | ||
|
||
Here are the command line options for btest: | ||
|
||
unix> ./btest -h | ||
Usage: ./btest [-hg] [-r <n>] [-f <name> [-1|-2|-3 <val>]*] [-T <time limit>] | ||
-1 <val> Specify first function argument | ||
-2 <val> Specify second function argument | ||
-3 <val> Specify third function argument | ||
-f <name> Test only the named function | ||
-g Format output for autograding with no error messages | ||
-h Print this message | ||
-r <n> Give uniform weight of n for all problems | ||
-T <lim> Set timeout limit to lim | ||
|
||
Examples: | ||
|
||
Test all functions for correctness and print out error messages: | ||
unix> ./btest | ||
|
||
Test all functions in a compact form with no error messages: | ||
unix> ./btest -g | ||
|
||
Test function foo for correctness: | ||
unix> ./btest -f foo | ||
|
||
Test function foo for correctness with specific arguments: | ||
unix> ./btest -f foo -1 27 -2 0xf | ||
|
||
Btest does not check your code for compliance with the coding | ||
guidelines. Use dlc to do that. | ||
|
||
******************* | ||
3. Helper Programs | ||
******************* | ||
|
||
We have included the ishow and fshow programs to help you decipher | ||
integer and floating point representations respectively. Each takes a | ||
single decimal or hex number as an argument. To build them type: | ||
|
||
unix> make | ||
|
||
Example usages: | ||
|
||
unix> ./ishow 0x27 | ||
Hex = 0x00000027, Signed = 39, Unsigned = 39 | ||
|
||
unix> ./ishow 27 | ||
Hex = 0x0000001b, Signed = 27, Unsigned = 27 | ||
|
||
unix> ./fshow 0x15213243 | ||
Floating point value 3.255334057e-26 | ||
Bit Representation 0x15213243, sign = 0, exponent = 0x2a, fraction = 0x213243 | ||
Normalized. +1.2593463659 X 2^(-85) | ||
|
||
linux> ./fshow 15213243 | ||
Floating point value 2.131829405e-38 | ||
Bit Representation 0x00e822bb, sign = 0, exponent = 0x01, fraction = 0x6822bb | ||
Normalized. +1.8135598898 X 2^(-126) | ||
|
||
|
||
|
Oops, something went wrong.