diff --git a/21st_century_c/chapter11/Makefile b/21st_century_c/chapter11/Makefile index 662fbfd..afd770f 100644 --- a/21st_century_c/chapter11/Makefile +++ b/21st_century_c/chapter11/Makefile @@ -1,4 +1,7 @@ -CFLAGS = -Wall -O0 --std=c11 -g -lm +CFLAGS = -Wall -Wextra --std=c11 -g -lm -ftest-coverage -fprofile-arcs + +.PHONY : all +all : simple_cplx seamlessone seamlesstwo dict_use simple_cplx : cplx.h complex.c simple_cplx.c @@ -10,13 +13,10 @@ seamlessone : seamlessone.c seamlesstwo : seamlesstwo.c $(CC) $(CFLAGS) -fms-extensions -Wno-microsoft $@.c -o $@ -dict_use : keyval.h keyval.c dict.h dict.c dict_use.c - $(CC) $(CFLAGS) keyval.c dict.c $@.c -o $@ +dict_use : memory.h memory.c keyval.h keyval.c dict.h dict.c dict_use.c + $(CC) $(CFLAGS) memory.c keyval.c dict.c $@.c -o $@ -.PHONY : all -all : simple_cplx seamlessone seamlesstwo dict_use - .PHONY : check check : *.h *.c cppcheck --enable=warning --enable=style *.c @@ -28,3 +28,6 @@ clean : rm -f seamlesstwo rm -f dict_use rm -rf *.dSYM + rm -rf *.gcno + rm -rf *.gcda + rm -rf *.gcov diff --git a/21st_century_c/chapter11/dict.c b/21st_century_c/chapter11/dict.c index cd912d3..7e4512b 100644 --- a/21st_century_c/chapter11/dict.c +++ b/21st_century_c/chapter11/dict.c @@ -1,5 +1,7 @@ #include #include + +#include "memory.h" #include "dict.h" @@ -14,12 +16,11 @@ dictionary *dictionary_new(void) { dictionary_not_found = &dnf; } dictionary *out = malloc(sizeof(dictionary)); - if(out != NULL) { - *out = (dictionary) {}; - } else { + if(out == NULL) { fprintf(stderr, "Out of memory.\n"); abort(); } + *out = (dictionary) {}; return out; } @@ -29,14 +30,13 @@ static void dictionary_add_keyval(dictionary *in, keyval *kv) { in->length++; keyval **tmp = realloc(in->pairs, sizeof(keyval*) * in->length); - if(tmp != NULL) { - in->pairs = tmp; - tmp = NULL; - in->pairs[in->length-1] = kv; - } else { + if(tmp == NULL) { fprintf(stderr, "Out of memory.\n"); abort(); } + in->pairs = tmp; + tmp = NULL; + in->pairs[in->length-1] = kv; } @@ -47,7 +47,11 @@ void dictionary_add(dictionary *in, char *key, void *value) { fprintf(stderr, "NULL is not a valid key.\n"); abort(); } - dictionary_add_keyval(in, keyval_new(key, value)); + if(dictionary_find(in, key) == dictionary_not_found) { + dictionary_add_keyval(in, keyval_new(key, value)); + } else { + printf("Key '%s' already exists!\n", key); + } } @@ -80,8 +84,8 @@ void dictionary_free(dictionary *in) { for (size_t i = 0; i < in->length; i++) { keyval_free(in->pairs[i]); } - free(in->pairs); - free(in); + safeFree(in->pairs); + safeFree(in); } diff --git a/21st_century_c/chapter11/dict_use.c b/21st_century_c/chapter11/dict_use.c index 27e52f5..38b2ac2 100644 --- a/21st_century_c/chapter11/dict_use.c +++ b/21st_century_c/chapter11/dict_use.c @@ -1,5 +1,6 @@ #include #include "dict.h" +#include "memory.h" @@ -13,11 +14,21 @@ int main() { dictionary_add(d, "an int", &zero); dictionary_add(d, "a float", &one); - dictionary_add(d, "a string", &two); + for (size_t i = 0; i < 10; i++) { + dictionary_add(d, "a string", &two); + } printf("The integer I recorded was: %i\n", *(int*) dictionary_find(d, "an int")); printf("The string I recorded was: %s\n", (char*) dictionary_find(d, "a string")); + dictionary *new_d = dictionary_copy(d); + dictionary_free(d); -} \ No newline at end of file + unsigned int three = 3; + + dictionary_add(new_d, "an uint", &three); + + dictionary_free(new_d); + +} diff --git a/21st_century_c/chapter11/keyval.c b/21st_century_c/chapter11/keyval.c index e0cb246..927a5d6 100644 --- a/21st_century_c/chapter11/keyval.c +++ b/21st_century_c/chapter11/keyval.c @@ -1,6 +1,8 @@ #include #include #include + +#include "memory.h" #include "keyval.h" @@ -10,12 +12,11 @@ Create a new key/value pair. */ keyval *keyval_new(char *key, void *value) { keyval *out = malloc(sizeof(keyval)); - if(out != NULL) { - *out = (keyval){.key = key, .value = value}; - } else { + if (out == NULL) { fprintf(stderr, "Out of memory.\n"); abort(); } + *out = (keyval){.key = key, .value = value}; return out; } @@ -25,12 +26,11 @@ the values in the old pair, not copies of their data. */ keyval *keyval_copy(const keyval *in) { keyval *out = malloc(sizeof(keyval)); - if(out != NULL) { - *out = *in; - } else { + if (out == NULL) { fprintf(stderr, "Out of memory.\n"); abort(); } + *out = *in; return out; } @@ -39,9 +39,7 @@ keyval *keyval_copy(const keyval *in) { Free a existing key/value pair. */ void keyval_free(keyval *in) { - if(in != NULL) { - free(in); - } + safeFree(in); } @@ -49,5 +47,5 @@ void keyval_free(keyval *in) { Check if key of key/value pair matches given key. */ int keyval_matches(const keyval *in, const char *key) { - return !strcasecmp(in->key, key); + return !strcmp(in->key, key); } diff --git a/21st_century_c/chapter11/memory.c b/21st_century_c/chapter11/memory.c new file mode 100644 index 0000000..695b258 --- /dev/null +++ b/21st_century_c/chapter11/memory.c @@ -0,0 +1,10 @@ +#include + + + +void saferFree(void **p) { + if (p != NULL && *p != NULL) { + free(*p); + p = NULL; + } +} diff --git a/21st_century_c/chapter11/memory.h b/21st_century_c/chapter11/memory.h new file mode 100644 index 0000000..3e1f5cd --- /dev/null +++ b/21st_century_c/chapter11/memory.h @@ -0,0 +1,3 @@ +void saferFree(void **p); + +#define safeFree(p) saferFree((void **) &(p)); diff --git a/21st_century_c/chapter11/seamlesstwo.c b/21st_century_c/chapter11/seamlesstwo.c index 408b967..f7d3173 100644 --- a/21st_century_c/chapter11/seamlesstwo.c +++ b/21st_century_c/chapter11/seamlesstwo.c @@ -38,4 +38,4 @@ int main() { double xylength = length(p.p2); printf("Its projection onto the XY plane is %g units from the origin\n", xylength); -} \ No newline at end of file +} diff --git a/21st_century_c/chapter11/simple_cplx.c b/21st_century_c/chapter11/simple_cplx.c index a478833..cf08f89 100644 --- a/21st_century_c/chapter11/simple_cplx.c +++ b/21st_century_c/chapter11/simple_cplx.c @@ -5,7 +5,7 @@ int main() { - int complex a = 1 + 2I; + complex int a = 1 + 2I; complex double b = 2 + I; gsl_complex c = gsl_cplx_from_c99(a); @@ -28,4 +28,4 @@ int main() { printf("v dot (1+2i) again\n"); gsl_vector_complex_print(dot(v, c)); -} \ No newline at end of file +}