Browse Source

added memory.h & memory.c with safeFree macro as safe wrapper around the free() function; use safeFree() instead of free()

T. Meissner 3 years ago
parent
commit
1ad6f920d0

+ 9
- 6
21st_century_c/chapter11/Makefile View File

@@ -1,4 +1,7 @@
1
-CFLAGS = -Wall -O0 --std=c11 -g -lm
1
+CFLAGS = -Wall -Wextra --std=c11 -g -lm -ftest-coverage -fprofile-arcs
2
+
3
+.PHONY : all
4
+all : simple_cplx seamlessone seamlesstwo dict_use
2 5
 
3 6
 
4 7
 simple_cplx : cplx.h complex.c simple_cplx.c
@@ -10,13 +13,10 @@ seamlessone : seamlessone.c
10 13
 seamlesstwo : seamlesstwo.c
11 14
 	$(CC) $(CFLAGS) -fms-extensions -Wno-microsoft $@.c -o $@
12 15
 
13
-dict_use : keyval.h keyval.c dict.h dict.c dict_use.c
14
-	$(CC) $(CFLAGS) keyval.c dict.c $@.c -o $@
16
+dict_use : memory.h memory.c keyval.h keyval.c dict.h dict.c dict_use.c
17
+	$(CC) $(CFLAGS) memory.c keyval.c dict.c $@.c -o $@
15 18
 
16 19
 
17
-.PHONY : all
18
-all : simple_cplx seamlessone seamlesstwo dict_use
19
-
20 20
 .PHONY : check
21 21
 check : *.h *.c
22 22
 	cppcheck --enable=warning --enable=style *.c
@@ -28,3 +28,6 @@ clean :
28 28
 	rm -f seamlesstwo
29 29
 	rm -f dict_use
30 30
 	rm -rf *.dSYM
31
+	rm -rf *.gcno
32
+	rm -rf *.gcda
33
+	rm -rf *.gcov

+ 15
- 11
21st_century_c/chapter11/dict.c View File

@@ -1,5 +1,7 @@
1 1
 #include <stdio.h>
2 2
 #include <stdlib.h>
3
+
4
+#include "memory.h"
3 5
 #include "dict.h"
4 6
 
5 7
 
@@ -14,12 +16,11 @@ dictionary *dictionary_new(void) {
14 16
     dictionary_not_found = &dnf;
15 17
   }
16 18
   dictionary *out = malloc(sizeof(dictionary));
17
-  if(out != NULL) {
18
-    *out = (dictionary) {};
19
-  } else {
19
+  if(out == NULL) {
20 20
     fprintf(stderr, "Out of memory.\n");
21 21
     abort();
22 22
   }
23
+  *out = (dictionary) {};
23 24
   return out;
24 25
 
25 26
 }
@@ -29,14 +30,13 @@ static void dictionary_add_keyval(dictionary *in, keyval *kv) {
29 30
 
30 31
   in->length++;
31 32
   keyval **tmp = realloc(in->pairs, sizeof(keyval*) * in->length);
32
-  if(tmp != NULL) {
33
-    in->pairs = tmp;
34
-    tmp = NULL;
35
-    in->pairs[in->length-1] = kv;
36
-  } else {
33
+  if(tmp == NULL) {
37 34
     fprintf(stderr, "Out of memory.\n");
38 35
     abort();
39 36
   }
37
+  in->pairs = tmp;
38
+  tmp = NULL;
39
+  in->pairs[in->length-1] = kv;
40 40
 
41 41
 }
42 42
 
@@ -47,7 +47,11 @@ void dictionary_add(dictionary *in, char *key, void *value) {
47 47
     fprintf(stderr, "NULL is not a valid key.\n");
48 48
     abort();
49 49
   }
50
-  dictionary_add_keyval(in, keyval_new(key, value));
50
+  if(dictionary_find(in, key) == dictionary_not_found) {
51
+    dictionary_add_keyval(in, keyval_new(key, value));
52
+  } else {
53
+    printf("Key '%s' already exists!\n", key);
54
+  }
51 55
 
52 56
 }
53 57
 
@@ -80,8 +84,8 @@ void dictionary_free(dictionary *in) {
80 84
   for (size_t i = 0; i < in->length; i++) {
81 85
     keyval_free(in->pairs[i]);
82 86
   }
83
-  free(in->pairs);
84
-  free(in);
87
+  safeFree(in->pairs);
88
+  safeFree(in);
85 89
 
86 90
 }
87 91
 

+ 13
- 2
21st_century_c/chapter11/dict_use.c View File

@@ -1,5 +1,6 @@
1 1
 #include <stdio.h>
2 2
 #include "dict.h"
3
+#include "memory.h"
3 4
 
4 5
 
5 6
 
@@ -13,11 +14,21 @@ int main() {
13 14
 
14 15
   dictionary_add(d, "an int", &zero);
15 16
   dictionary_add(d, "a float", &one);
16
-  dictionary_add(d, "a string", &two);
17
+  for (size_t i = 0; i < 10; i++) {
18
+    dictionary_add(d, "a string", &two);
19
+  }
17 20
 
18 21
   printf("The integer I recorded was: %i\n", *(int*) dictionary_find(d, "an int"));
19 22
   printf("The string I recorded was: %s\n", (char*) dictionary_find(d, "a string"));
20 23
 
24
+  dictionary *new_d = dictionary_copy(d);
25
+
21 26
   dictionary_free(d);
22 27
 
23
-}
28
+  unsigned int three = 3;
29
+
30
+  dictionary_add(new_d, "an uint", &three);
31
+
32
+  dictionary_free(new_d);
33
+
34
+}

+ 8
- 10
21st_century_c/chapter11/keyval.c View File

@@ -1,6 +1,8 @@
1 1
 #include <stdio.h>
2 2
 #include <stdlib.h>
3 3
 #include <strings.h>
4
+
5
+#include "memory.h"
4 6
 #include "keyval.h"
5 7
 
6 8
 
@@ -10,12 +12,11 @@ Create a new key/value pair.
10 12
 */
11 13
 keyval *keyval_new(char *key, void *value) {
12 14
   keyval *out = malloc(sizeof(keyval));
13
-  if(out != NULL) {
14
-    *out = (keyval){.key = key, .value = value};
15
-  } else {
15
+  if (out == NULL) {
16 16
     fprintf(stderr, "Out of memory.\n");
17 17
     abort();
18 18
   }
19
+  *out = (keyval){.key = key, .value = value};
19 20
   return out;
20 21
 }
21 22
 
@@ -25,12 +26,11 @@ the values in the old pair, not copies of their data.
25 26
 */
26 27
 keyval *keyval_copy(const keyval *in) {
27 28
   keyval *out = malloc(sizeof(keyval));
28
-  if(out != NULL) {
29
-    *out = *in;
30
-  } else {
29
+  if (out == NULL) {
31 30
     fprintf(stderr, "Out of memory.\n");
32 31
     abort();
33 32
   }
33
+  *out = *in;
34 34
   return out;
35 35
 }
36 36
 
@@ -39,9 +39,7 @@ keyval *keyval_copy(const keyval *in) {
39 39
 Free a existing key/value pair.
40 40
 */
41 41
 void keyval_free(keyval *in) {
42
-  if(in != NULL) {
43
-    free(in);
44
-  }
42
+  safeFree(in);
45 43
 }
46 44
 
47 45
 
@@ -49,5 +47,5 @@ void keyval_free(keyval *in) {
49 47
 Check if key of key/value pair matches given key.
50 48
 */
51 49
 int keyval_matches(const keyval *in, const char *key) {
52
-  return !strcasecmp(in->key, key);
50
+  return !strcmp(in->key, key);
53 51
 }

+ 10
- 0
21st_century_c/chapter11/memory.c View File

@@ -0,0 +1,10 @@
1
+#include <stdlib.h>
2
+
3
+
4
+
5
+void saferFree(void **p) {
6
+  if (p != NULL && *p != NULL) {
7
+    free(*p);
8
+    p = NULL;
9
+  }
10
+}

+ 3
- 0
21st_century_c/chapter11/memory.h View File

@@ -0,0 +1,3 @@
1
+void saferFree(void **p);
2
+
3
+#define safeFree(p) saferFree((void **) &(p));

+ 1
- 1
21st_century_c/chapter11/seamlesstwo.c View File

@@ -38,4 +38,4 @@ int main() {
38 38
   double xylength = length(p.p2);
39 39
   printf("Its projection onto the XY plane is %g units from the origin\n", xylength);
40 40
 
41
-}
41
+}

+ 2
- 2
21st_century_c/chapter11/simple_cplx.c View File

@@ -5,7 +5,7 @@
5 5
 
6 6
 int main() {
7 7
 
8
-  int complex a = 1 + 2I;
8
+  complex int a = 1 + 2I;
9 9
   complex double b = 2 + I;
10 10
   gsl_complex c = gsl_cplx_from_c99(a);
11 11
 
@@ -28,4 +28,4 @@ int main() {
28 28
   printf("v dot (1+2i) again\n");
29 29
   gsl_vector_complex_print(dot(v, c));
30 30
 
31
-}
31
+}