The readings for Monday, March 27 are:
The focus of this reading is to introduce you to dynamic memory and structs in C. In particular, you should become familiar with malloc and free.
Given the following lines of code in C99:
struct point { double x; double y; }; ... 1. int i = 0; 2. int a[] = {4, 6, 6, 3, 7}; 3. char *s = "pgui"; 4. struct point p = {0, 0}; 5. struct point *q = NULL; 6. struct point *x = malloc(sizeof(struct point)); 7. struct point *y = malloc(10*sizeof(struct point)); 8. struct point **z = malloc(10*sizeof(struct point *));
How much memory (in terms of bytes) is allocated or reserved
for each of the 8
declarations above (assume a 64
bit Linux machine
such as the student machines)?
Note: Remember that each variable declaration is a memory allocation.
Given the following C99 file duplicates.c:
/* duplicates.c */ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <time.h> const int NITEMS = 1<<10; const int TRIALS = 100; bool contains(int *a, int n, int k) { /* TODO: Search through array to see if there is an element that matches key */ return false; } bool duplicates(int n) { int *randoms = malloc(n); for (int i = 0; i < n; i++) randoms[i] = rand(); for (int i = 0; i < n; i++) { /* TODO: Use contains to search array for duplicate */ if (true) { return true; } } free(randoms); return false; } int main(int argc, char *argv[]) { srand(time(NULL)); for (int i = 0; i < TRIALS; i++) if (duplicates(NITEMS)) puts("Duplicates detected!"); return 0; }
First, download the duplicates.c and Makefile.reading08 starter code:
# Download duplicates.c $ curl -L https://www3.nd.edu/~pbui/teaching/cse.20289.sp17/static/c/duplicates.c > duplicates.c # Download Makefile.reading08 $ curl -L https://www3.nd.edu/~pbui/teaching/cse.20289.sp17/static/txt/Makefile.reading08 > Makefile
contains
Implement the contains
function:
Given an integer array
a
, its sizen
, and a keyk
, this returns whether or nota
contains an element with the samek
value.
duplicates
Complete the duplicates
function:
Given an integer
n
, this function generatesn
random integers and stores them into anrandoms
array. It then uses thecontains
function to check if each element in the array has a duplicate. It returnstrue
if a duplicate is found andfalse
if there are no duplicates.
Note: Simply replace the if (true)
with something in the form if
(contains(...))
.
Once you are confident in your implementations of contains
and
duplicates
, use the Makefile to build and test your code:
# Build and run test $ make test gcc -g -gdwarf-2 -Wall -std=gnu99 -c -o duplicates.o duplicates.c gcc -L. -o duplicates duplicates.o Testing duplicates... make: *** [Makefile:17: test] Error 1
Most likely, the test will fail. To view the error output from
valgrind, you can look at the test.log
file the Makefile
generates during testing:
# View Valgrind log $ cat test.log ==16711== Memcheck, a memory error detector ==16711== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==16711== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info ==16711== Command: ./duplicates ==16711== ==16711== Invalid write of size 4 ==16711== at 0x4006AB: duplicates (duplicates.c:20) ==16711== by 0x40071B: main (duplicates.c:37) ==16711== Address 0x51d5440 is 0 bytes after a block of size 1,024 alloc'd ==16711== at 0x4C2AC00: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==16711== by 0x400683: duplicates (duplicates.c:17) ==16711== by 0x40071B: main (duplicates.c:37) ==16711== --16711-- VALGRIND INTERNAL ERROR: Valgrind received a signal 7 (SIGBUS) - exiting --16711-- si_code=128; Faulting address: 0x0; sp: 0x802ca9e30 ....
You should see something like the above output. Debug this memory error
(and any other errors) so that make test
passes.
Note: You should not need to add any free statements to fix this memory error.
Once your code is passing the test, modify the following line of code:
randoms[i] = rand();
To the following:
randoms[i] = rand() % 1000;
Run make test
again:
# Build and run test $ make test gcc -g -gdwarf-2 -Wall -std=gnu99 -c -o duplicates.o duplicates.c gcc -L. -o duplicates duplicates.o Testing duplicates... make: *** [Makefile:17: test] Error 1
Most likely, the test will fail. Once again, view the error output from valgrind:
$ tail -n 20 test.log Duplicates detected! ==17270== ==17270== HEAP SUMMARY: ==17270== in use at exit: 409,600 bytes in 100 blocks ==17270== total heap usage: 101 allocs, 1 frees, 413,696 bytes allocated ==17270== ==17270== 409,600 bytes in 100 blocks are definitely lost in loss record 1 of 1 ==17270== at 0x4C2AC00: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==17270== by 0x400687: duplicates (duplicates.c:17) ==17270== by 0x40071F: main (duplicates.c:37) ==17270== ==17270== LEAK SUMMARY: ==17270== definitely lost: 409,600 bytes in 100 blocks ==17270== indirectly lost: 0 bytes in 0 blocks ==17270== possibly lost: 0 bytes in 0 blocks ==17270== still reachable: 0 bytes in 0 blocks ==17270== suppressed: 0 bytes in 0 blocks ==17270== ==17270== For counts of detected and suppressed errors, rerun with: -v ==17270== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
You should see something like the above output. Debug this memory leak
(and any other errors) so that make test
passes.
README.md
In your README.md
, answer the following questions:
Describe what the memory error was in Task 3
and how you fixed it.
Describe what the memory leak was in Task 4
and how you fixed it.
If you have any questions, comments, or concerns regarding the course, please provide your feedback at the end of your response.
To submit your assignment, please commit your work to the reading08
folder
in your assignments GitLab repository. Your reading08
folder should
only contain the following files:
README.md
Makefile
duplicates.c