
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
containsImplement the contains function:
Given an integer array
a, its sizen, and a keyk, this returns whether or notacontains an element with the samekvalue.
duplicatesComplete the duplicates function:
Given an integer
n, this function generatesnrandom integers and stores them into anrandomsarray. It then uses thecontainsfunction to check if each element in the array has a duplicate. It returnstrueif a duplicate is found andfalseif 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.mdIn 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.mdMakefileduplicates.c