Line data Source code
1 : #include <stdio.h>
2 : #include <string.h>
3 : #include <stdlib.h>
4 :
5 : static size_t mallocs;
6 : static size_t frees;
7 :
8 0 : static void check_memory_leaks(void)
9 : {
10 : size_t leaks;
11 :
12 0 : leaks = mallocs-frees;
13 :
14 0 : if (leaks == 0)
15 0 : return;
16 :
17 0 : fprintf(stderr, "----------------------------------------------\n");
18 :
19 0 : if (frees > mallocs) {
20 0 : fprintf(stderr, "undefined behavior detected: more frees (%zu) than allocations (%zu)\n",
21 : frees, mallocs);
22 : } else {
23 :
24 0 : fprintf(stderr, "fatal program error detected: memory leak");
25 :
26 0 : fprintf(stderr, "\nnumber of allocations in use: %15zu\n", mallocs-frees);
27 : }
28 :
29 0 : fprintf(stderr, "\ngoodbye, terminating abnormally...\n");
30 0 : fprintf(stderr, "----------------------------------------------\n");
31 :
32 0 : abort();
33 : }
34 :
35 0 : static void init(void)
36 : {
37 : static unsigned char initialized;
38 :
39 0 : if (initialized)
40 0 : return;
41 :
42 0 : atexit(check_memory_leaks);
43 :
44 0 : initialized = 1;
45 : }
46 :
47 0 : void* __check_malloc(size_t s)
48 : {
49 : void* p;
50 :
51 0 : if (s == 0)
52 0 : return NULL;
53 :
54 0 : init();
55 :
56 0 : p = malloc(s);
57 :
58 0 : if (p != NULL)
59 0 : mallocs += 1;
60 :
61 0 : return p;
62 : }
63 :
64 0 : void* __check_calloc(size_t s, size_t n)
65 : {
66 : void* p;
67 : size_t total;
68 :
69 0 : total = s * n;
70 :
71 0 : p = __check_malloc(total);
72 :
73 0 : if (p == NULL)
74 0 : return NULL;
75 :
76 0 : memset(p, 0, total);
77 :
78 0 : return p;
79 : }
80 :
81 0 : void __check_free(void* p)
82 : {
83 0 : if (p != NULL) {
84 0 : frees += 1;
85 0 : free(p);
86 : }
87 0 : }
88 :
89 0 : void* __check_realloc(void* p, size_t s)
90 : {
91 0 : if (s == 0) {
92 0 : __check_free(p);
93 0 : return NULL;
94 0 : } else if (p == NULL)
95 0 : return __check_malloc(s);
96 : else
97 0 : return realloc(p, s);
98 : }
|