FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_malloc.c
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9#include <errno.h>
10#include "hecmw_config.h"
11#include "hecmw_util.h"
12#include "hecmw_malloc.h"
13
15 void *ptr;
16 size_t size;
17 char *file;
18 int line;
20};
21
22static struct malloc_info *mainfo;
23
24static int is_check_memleak;
25
26static long mem_size;
27
28static int auto_check = 1;
29
30static int n_ptr;
31
32static int add_info(void *ptr, size_t size, char *file, int line) {
33 static struct malloc_info *info;
34 int rtc;
35
37
38 #pragma omp critical
39 {
40 info = malloc(sizeof(*info));
41 if (info == NULL) {
42 rtc = -1;
43 } else {
44 mem_size += size;
45
46 info->ptr = ptr;
47 info->size = size;
48 info->file = file;
49 info->line = line;
50 info->next = mainfo;
51
52 mainfo = info;
53
54 n_ptr++;
55 rtc = 0;
56 }
57 }
58
59 return rtc;
60}
61
62static int del_info(void *ptr) {
63 struct malloc_info *p, *q;
64 int rtc, i;
65
67
68 #pragma omp critical
69 {
70 q = NULL;
71 for (p = mainfo, i = 0; p && p->ptr != ptr; p = (q = p)->next, i++) {
72 HECMW_assert(i < n_ptr);
73 }
74 if (p == NULL) {
75 rtc = -1; /* not found */
76 } else {
77 if (q == NULL) {
78 mainfo = p->next;
79 } else {
80 q->next = p->next;
81 }
82 mem_size -= p->size;
83 free(p);
84
85 n_ptr--;
86 rtc = 0;
87 }
88 }
89 return rtc;
90}
91
92static int change_info(void *ptrold, void *ptrnew, size_t sizenew, char *file,
93 int line) {
94 struct malloc_info *p;
95 long size;
96 int rtc, i;
97
98 HECMW_assert(ptrold);
99 HECMW_assert(ptrnew);
100
101 #pragma omp critical
102 {
103 for (p = mainfo, i = 0; p && p->ptr != ptrold; p = p->next, i++) {
104 HECMW_assert(i < n_ptr);
105 }
106 if (p == NULL) {
107 rtc = -1;
108 } else {
109 size = sizenew - p->size;
110 mem_size += size;
111 p->ptr = ptrnew;
112 p->size = sizenew;
113 p->file = file;
114 p->line = line;
115 rtc = 0;
116 }
117 }
118 return rtc;
119}
120
121int HECMW_list_meminfo(FILE *fp) {
122 int n;
123 struct malloc_info *p;
124
125 if (fp == NULL) fp = stdout;
126
127 n = 0;
128 for (p = mainfo; p; p = p->next) {
129 fprintf(fp, "HEC-MW memory info: %s:%d ptr=%p size=%d\n", p->file,
130 p->line, p->ptr, (int)p->size);
131 n++;
132 }
133 return n;
134}
135
136void HECMW_set_autocheck_memleak(int flag) { auto_check = flag ? 1 : 0; }
137
139 int n;
140 struct malloc_info *p;
141
142 if (mainfo == NULL) return 0; /* no memory leaks */
143 n = 0;
144 for (p = mainfo; p; p = p->next) {
145 fprintf(stderr,
146 "HEC-MW memory check: "
147 "A memory leak found at %s:%d ptr=%p size=%d\n",
148 p->file, p->line, p->ptr, (int)p->size);
149 n++;
150 }
151 fprintf(stderr,
152 "HEC-MW memory check: "
153 "%d memory leak%s found\n",
154 n, (n > 1) ? "s" : "");
155 return n;
156}
157
158static void check_memleak(void) { HECMW_check_memleak(); }
159
160static int mark_check_memleak(void) {
161 if (!is_check_memleak) {
162 if (atexit(check_memleak) == -1) return -1;
163 is_check_memleak = 1;
164 }
165 return 0;
166}
167
168long HECMW_get_memsize(void) { return mem_size; }
169
170void HECMW_free_(void *ptr, char *file, int line) {
171 if (ptr == NULL) return;
172 if (del_info(ptr)) {
174 "Not found allocated memory %p(%s:%d)\n", ptr, file, line);
175 }
176 free(ptr);
177}
178
179void *HECMW_malloc_(size_t size, char *file, int line) {
180 void *ptr = NULL;
181
182 ptr = malloc(size);
183 if (ptr == NULL) goto error;
184 if (add_info(ptr, size, file, line)) goto error;
185 if (auto_check) {
186 if (mark_check_memleak()) goto error;
187 }
188 return ptr;
189error:
190 free(ptr);
191 return NULL;
192}
193
194void *HECMW_calloc_(size_t nmemb, size_t size, char *file, int line) {
195 void *ptr = NULL;
196
197 ptr = calloc(nmemb, size);
198 if (ptr == NULL) goto error;
199 if (add_info(ptr, nmemb * size, file, line)) goto error;
200 if (auto_check) {
201 if (mark_check_memleak()) goto error;
202 }
203 return ptr;
204error:
205 free(ptr);
206 return NULL;
207}
208
209void *HECMW_realloc_(void *ptr, size_t size, char *file, int line) {
210 void *ptrnew;
211
212 ptrnew = realloc(ptr, size);
213
214 if (size == 0 && ptr != NULL) { /* same as free */
215 if (del_info(ptr)) {
217 "Not found registered memory %p(%s:%d)\n", ptr, file,
218 line);
219 }
220 return NULL;
221 }
222 if (ptr == NULL) { /* same as malloc(size) */
223 if (add_info(ptrnew, size, file, line)) return NULL;
224 } else {
225 if (ptr == ptrnew) {
226 if (change_info(ptr, ptrnew, size, file, line)) {
228 "Not found registered memory %p(%s:%d)\n", ptr, file,
229 line);
230 if (add_info(ptrnew, size, file, line)) return NULL;
231 }
232 } else {
233 if (del_info(ptr)) {
235 "Not found registered memory %p(%s:%d)\n", ptr, file,
236 line);
237 }
238 if (add_info(ptrnew, size, file, line)) goto error;
239 }
240 }
241 if (auto_check) {
242 if (mark_check_memleak()) goto error;
243 }
244 return ptrnew;
245error:
246 return NULL;
247}
248
249char *HECMW_strdup_(const char *s, char *file, int line) {
250 char *str = NULL;
251 str = strdup(s);
252 if (str == NULL) goto error;
253 if (add_info(str, strlen(str) + 1, file, line)) goto error;
254 if (auto_check) {
255 if (mark_check_memleak()) goto error;
256 }
257 return str;
258error:
259 free(str);
260 return NULL;
261}
#define NULL
#define HECMW_LOG_WARN
Definition: hecmw_log.h:17
void HECMW_set_autocheck_memleak(int flag)
Definition: hecmw_malloc.c:136
void * HECMW_realloc_(void *ptr, size_t size, char *file, int line)
Definition: hecmw_malloc.c:209
void * HECMW_calloc_(size_t nmemb, size_t size, char *file, int line)
Definition: hecmw_malloc.c:194
void * HECMW_malloc_(size_t size, char *file, int line)
Definition: hecmw_malloc.c:179
int HECMW_list_meminfo(FILE *fp)
Definition: hecmw_malloc.c:121
long HECMW_get_memsize(void)
Definition: hecmw_malloc.c:168
char * HECMW_strdup_(const char *s, char *file, int line)
Definition: hecmw_malloc.c:249
int HECMW_check_memleak(void)
Definition: hecmw_malloc.c:138
void HECMW_free_(void *ptr, char *file, int line)
Definition: hecmw_malloc.c:170
#define HECMW_UTIL_E9001
Definition: hecmw_msgno.h:370
void HECMW_print_msg(int loglv, int msgno, const char *fmt,...)
Definition: hecmw_util.c:138
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
void * ptr
Definition: hecmw_malloc.c:15
size_t size
Definition: hecmw_malloc.c:16
struct malloc_info * next
Definition: hecmw_malloc.c:19
char * file
Definition: hecmw_malloc.c:17