lab0

Contents

Lab 0: C Warmup                                1
  Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
  Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
  Acquiring the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
  Compiling and running the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
  Submitting the exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3


Lab 0: C Warmup
Overview
The purpose of this assignment is to gain some basic experience with C programming, including such topics
as arrays, stack allocation, heap allocation, function calls, and memory safety (or the lack thereof). It is a
credit/no credit exercise and should take a short time to finish.


Development Environment
Since we want to make sure that all students have a working (and generally equivalent) development
environment, we are providing a Virtual Machine (VM) to use. Your first task, before starting any programming
assignment, will be to ensure that your VM is setup correctly as outlined by the instructions page. The VM
we give you will be the only officially supported environment for all programming assignments
and will be used throughout the course.


Acquiring the code
Once your VM has been properly setup, you will now be able to retrieve the provided code for this assignment.
To do so, you will have to use the update-course script located on the course VM. This script may be run
from a command-line terminal or by using the launcher located on the top toolbar or by using the launcher on
the desktop. This script will place all necessary files in the “course-materials” sub-directory within your home
folder. For convenience, a shortcut to this directory has been placed on the desktop. It is important to
our infrastructure that you do not move/rename any files in the “course-materials” directory.
Also, you should not change any files in this directory except for those that we note. You may,
however, copy files until your heart’s content.


Now that you have acquired the source file, open arrays.c in your favorite text editor. arrays.c file contains a
number of TODOs, which you are expected to complete. Most have a proceeding line that says “Answer:”,
which is where you should leave an answer to the question(s) posed in the TODO. One TODO requires you
to write some code, which you should place immediately after the comment block that describes what to do.
As a convenience, here is an archive of the course-materials directory for this lab: lab0.tar.gz.

Compiling and running the code
The source file arrays.c won’t do you any good by itself; you need a compiler (specifically the GNU C compiler)
to compile it to an executable format. The GNU C compiler is available on the VM and most popular variants
of Linux, such as Ubuntu and Fedora. You’re free to use whichever machine you like, although we will only
provide support for the VM.
Using the VM (or your own system if you’re adventurous!), open a terminal and execute gcc -v. On our
machine, here is what we see:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bu
gs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --prog
ram-suffix=-4.6 --enable-shared --enable-linker-build-id --with-syste
m-zlib --libexecdir=/usr/lib --without-included-gettext --enable-thre
ads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/l
ib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstd
cxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --en
able-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --w
ith-tune=generic --enable-checking=release --build=x86_64-linux-gnu -
-host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)


The output tells us a bunch of the configuration options for the our installation of GCC as well as the version
number, which is 4.6.3. Navigate to the “~/course-materials/lab0” directory (where ~ denotes your home
directory) and then use GCC to compile arrays.c with the following command:

gcc -g -Wall -std=gnu99 -o arrays arrays.c


It’s not that important right now for you to know what all of these options do, but -g tells the compiler to
include debugging symbols, -Wall says to print warnings for all types of potential problems, -std=gnu99 says
to use the C99 standard (now only 14 years old!), -o arrays instructs the compiler to output the executable
code to a file called arrays, and arrays.c is the source file being compiled.
Having executed that command, you should be able to see a file named arrays in the same directory:

$ ls
arrays  arrays.c


The arrays file is an executable file, which you can run using ./arrays. On our machine, here is what we see:

$ ./arrays
Filling an array at address 0x7fff6b4e3e60 with 10 values
Done!
Filling an array at address 0x7fff6b4e3eac with 1 values
2
Done!
Filling an array at address 0x7fff6b4e3e90 with 4 values
Done!
Filling an array at address 0x11ca010 with 5 values
Done!


If you look through the source code of the arrays.c file, you should be able to match up each line that is
printed with the output that you see in the console.
With that, you should have everything you need to complete the assignment. Note that every time you want
to test a modification to the source file, you will need to use the gcc -g -Wall -std=gnu99 -o arrays
arrays.c command to produce an updated arrays executable file.
Checking your work
When you have finished the exercise, please take the time to ensure that your code both compiles without
warnings (the GCC command will output lines that say “warning:” if you have warnings) and is readable. In
particular, please try to make the format of your code match that of what was given to you.


Submitting the exercise
You will be able to submit your assignment with the submit-hw script that is bundled with the lab0 course-
materials update. Using the script should be straight-forward, but it does expect you to not move/rename
any files from the “course-materials” directory. Open a terminal and type the following command:

submit-hw lab0


The script will then prompt you for your Coursera username and then your submission password. Your
submission password is NOT the same as your regular Coursera account password!!!! You may
locate your submission password at the top of the assignments list page. With a working Internet connection,
this should submit your code properly. You can go to the assignments list page to double-check that it
has been submitted and check your score as well as any feedback the auto-grader gives you. You may also
download your submission code here, if you wish.

 

Implementation

  1 // These #includes tell the compiler to include the named
  2 // header files, similar to imports in Java. The code for
  3 // these is generally located under /usr/include/, such
  4 // as /usr/include/assert.h. assert.h contains the
  5 // declaration of the assert() function, stdio.h contains
  6 // the declaration of the printf() function, and stdlib.h
  7 // contains the declaration of the malloc() and free()
  8 // functions, all of which are used in the code below.
  9 #include 
 10 #include 
 11 #include 
 12 
 13 // Fill the given array with values. Note that C doesn't
 14 // keep track of the length of arrays, so we have to
 15 // specify it explictly here.
 16 void fillArray(int* array, int len) {
 17   printf("Filling an array at address %p with %d "
 18          "values\n", array, len);
 19   for (int i = 0; i < len; ++i) {
 20     array[i] = i * 3 + 2;
 21     // assert() verifies that the given condition is true
 22     // and exits the program otherwise. This is just a
 23     // "sanity check" to make sure that the line of code
 24     // above is doing what we intend.
 25     assert(array[i] == i * 3 + 2);
 26   }
 27   printf("Done!\n");
 28 }
 29 
 30 // Structs are simply storage for memory of various types.
 31 // In this case, we are typedef-ing (as in naming) a
 32 // struct containing four integers as FourInts.
 33 typedef struct {
 34   int a, b, c, d;
 35 } FourInts;
 36 
 37 // main() is the entry point of the program.
 38 int main(int argc, char* argv[]) {
 39   // Create a new array capable of storing 10 elements
 40   // and fill it with values using the function declared
 41   // above. Arrays declared in this manner are located on
 42   // the stack, which is where statically allocated (as
 43   // in not at runtime) memory is stored.
 44   int array[10];
 45   // The "array" that we pass here is actually a pointer
 46   // to a block of memory capable of storing 10 integers.
 47   // array[0] is the first integer in this block of
 48   // memory, array[1] is the second, and so on. Since
 49   // C does not track array lengths, we have to specify
 50   // how many elements the array contains.
 51   //
 52   // TODO(1): What happens if the second argument is set
 53   // to 11 instead? How about 100? 1000? Make sure to set
 54   // the second argument back to 10 when you are done
 55   // testing.
 56   // Answer:
 57   fillArray(array, 10);
 58 
 59   int value;
 60   // In C, we can take the address of something using the
 61   // & operator. &value is of the type int*, meaning that
 62   // it is a pointer to an integer (as in it stores the
 63   // address in memory of where the actual int is located).
 64   //
 65   // TODO(2): We can actually use the address of the value
 66   // declared here as if it were an array of a single
 67   // element; why is this possible?
 68   // Answer:
 69   fillArray(&value, 1);
 70   // fillArray should set value to 0 * 3 + 2 = 2.
 71   assert(value == 2);
 72 
 73   // The following creates an instance of FourInts on the
 74   // stack. FourInts is really just an array of four ints,
 75   // although we can refer to the ints stored in it by
 76   // name as well.
 77   FourInts four_ints;
 78   // Set the first int to have a value of 0 and verify
 79   // that the value changed.
 80   four_ints.a = 0;
 81   assert(four_ints.a == 0);
 82 
 83   // Depending on whether or not you like to live
 84   // dangerously, the following is either exciting or
 85   // terrifying. Though &four_ints is of type FourInts*
 86   // (as in a pointer to a FourInts struct), we can
 87   // use a cast to pretend that it is actually an array
 88   // of integers instead.
 89   fillArray((int*) &four_ints, 4);
 90   // We can confirm that fillArray updated the values
 91   // in the FourInts struct:
 92   assert(four_ints.a == 2);
 93   assert(four_ints.b == 5);
 94   assert(four_ints.c == 8);
 95   assert(four_ints.d == 11);
 96 
 97   // In the case that the size of an array is not known
 98   // until runtime, the malloc() function can be used to
 99   // allocate memory dynamically. Memory that is
100   // allocated dynamically is stored on the heap, which
101   // is separate from the stack. C is unlike Java,
102   // however, in that dynamically-allocated memory must
103   // be freed explicitly when the program is done using
104   // it via the free() function. malloc() takes a single
105   // argument, which is the number of bytes to allocate.
106   // sizeof(int) gives how many bytes an int contains
107   // (which is four), so sizeof(int) * 5 is 20.
108   int* heap_array = (int*) malloc(sizeof(int) * 5);
109   fillArray(heap_array, 5);
110   // Now that we have finished with the heap-allocated
111   // array, free() the memory associated with it.
112   //
113   // TODO(3): What happens if we remove the free()
114   // statement below? Try running "valgrind ./arrays"
115   // after compiling the program both with and without
116   // it. valgrind is a tool for analyzing how programs
117   // use memory, which is often invaluable for C and
118   // C++ programming.
119   // Answer:
120   free(heap_array);
121 
122   // TODO(4): Now it's your turn to write some code.
123   // Using malloc(), allocate a FourInts struct
124   // dynamically (on the heap) and use fillArray to
125   // populate it with values. Make sure to free the
126   // memory when you are done, and use the valgrind
127   // tool mentioned above to check that there aren't
128   // any errors. As a "sanity check," add four assert
129   // statements to verify that the a, b, c, and d
130   // fields of the FourInts struct are set to what
131   // you would expect. (Hint, you'll need to use the
132   // -> operator to access fields of a FourInts*
133   // variable instead of the . operator).
134   int* heap_four = (int*) malloc(sizeof(FourInts));
135   fillArray(heap_four,4);
136 
137   assert(four_ints.a == 2);
138   assert(four_ints.b == 5);
139   assert(four_ints.c == 8);
140   assert(four_ints.d == 11);
141 
142   return 0;
143 }

 

Excecution

bash-4.2$ cd Desktop/course-materials/lab0
bash-4.2$ gcc -g -Wall -std=gnu99 -o arrays arrays.c
bash-4.2$ ./arrays
Filling an array at address 0x7fff58a9be50 with 10 values
Done!
Filling an array at address 0x7fff58a9be4c with 1 values
Done!
Filling an array at address 0x7fff58a9be30 with 4 values
Done!
Filling an array at address 0x2549010 with 5 values
Done!
Filling an array at address 0x2549010 with 4 values
Done!
bash-4.2$ valgrind ./arrays
==2221== Memcheck, a memory error detector
==2221== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==2221== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==2221== Command: ./arrays
==2221== 
Filling an array at address 0x7ff0005b0 with 10 values
Done!
Filling an array at address 0x7ff0005ac with 1 values
Done!
Filling an array at address 0x7ff000590 with 4 values
Done!
Filling an array at address 0x4c30040 with 5 values
Done!
Filling an array at address 0x4c300a0 with 4 values
Done!
==2221== 
==2221== HEAP SUMMARY:
==2221==     in use at exit: 16 bytes in 1 blocks
==2221==   total heap usage: 2 allocs, 1 frees, 36 bytes allocated
==2221== 
==2221== LEAK SUMMARY:
==2221==    definitely lost: 16 bytes in 1 blocks
==2221==    indirectly lost: 0 bytes in 0 blocks
==2221==      possibly lost: 0 bytes in 0 blocks
==2221==    still reachable: 0 bytes in 0 blocks
==2221==         suppressed: 0 bytes in 0 blocks
==2221== Rerun with --leak-check=full to see details of leaked memory
==2221== 
==2221== For counts of detected and suppressed errors, rerun with: -v
==2221== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
bash-4.2$ 

 

转载于:https://www.cnblogs.com/Aegis-Liang/p/4911731.html

你可能感兴趣的:(lab0)