diff --git a/lab02/.gitignore b/lab02/.gitignore new file mode 100644 index 0000000..d3705e5 --- /dev/null +++ b/lab02/.gitignore @@ -0,0 +1,10 @@ +.*.swp +*.o +test_leap +*.creator* +*.cflags +*.config +*.cxxflags +*.files +*.includes +.vscode/ diff --git a/lab02/README.md b/lab02/README.md new file mode 100644 index 0000000..52df9e7 --- /dev/null +++ b/lab02/README.md @@ -0,0 +1,9 @@ +# CITS3007 lab 2 demo repository + +This repository contains a Makefile and C code for two programs, +"factorial" and "segfault". + +## Building + +Build with `make`. + diff --git a/lab02/factorial.c b/lab02/factorial.c new file mode 100644 index 0000000..9b09bad --- /dev/null +++ b/lab02/factorial.c @@ -0,0 +1,59 @@ + +#include +#include +#include + +// contains INT_MAX +#include + +/* return the factorial of n. + * The result is undefined if n < 0. + * + * The largest factorial that can be calculated depends + * on your platform. On platforms where a `long` + * is 8 bytes, the results of the function for + * any n greater than 20 are undefined. + */ +long factorial(int n) { + long result = 1; + for (int i = n; i > 0; i--) { + result = result * i; + } + return result; +} + +int main(int argc, char **argv) { + argc--; + argv++; + + if (argc != 1) { + fprintf(stderr, "Error: expected 1 command-line argument (an INT), but got %d\n", argc); + exit(1); + } + + char *end; + + // clear errno so we can check whether strtol fails + errno = 0; + long n = strtol(argv[0], &end, 10); + int res_errno = errno; + + if (end == argv[0]) { + fprintf(stderr, "Error: couldn't interpret '%s' as a number\n", argv[0]); + exit(1); + } else if (res_errno == ERANGE) { + fprintf(stderr, "Error: '%s' is outside the range of numbers we can handle\n", argv[0]); + exit(1); + } else if (n > INT_MAX) { + fprintf(stderr, "Error: '%s' is too big to fit in an int\n", argv[0]); + exit(1); + } else if (n < 0) { + fprintf(stderr, "Error: invalid value %ld:" + "factorial can only be calculated for non-negative numbers\n", n); + exit(1); + } + + int nn = (short) n; + long result = factorial(nn); + printf("factorial(%d) is %ld\n", nn, result); +} diff --git a/lab02/segfault.c b/lab02/segfault.c new file mode 100644 index 0000000..ca7dc07 --- /dev/null +++ b/lab02/segfault.c @@ -0,0 +1,27 @@ + +#include +#include + +#define STR_BUF_SIZE 1024 + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) +#define CHECK_ALLOC(block) \ + if (block == 0) \ + { \ + printf("malloc() failed at " STR(__LINE__) ". Exited."); \ + exit(-1); \ + } + +int main(void) +{ + char *buf; + buf = malloc(STR_BUF_SIZE); // allocate a large buffer + CHECK_ALLOC(buf) + + printf("type some text and hit 'return':\n"); + fgets(buf, STR_BUF_SIZE, stdin); // read 1024 chars into buf + printf("\n%s\n\n", buf); // print what was entered + free(buf); + return 0; +}