1 /* @source ajmem **************************************************************
2 **
3 ** AJAX memory functions
4 **
5 ** @author Copyright (C) 1999 Peter Rice
6 ** @version $Revision: 1.35 $
7 ** @modified Peter Rice pmr@ebi.ac.uk
8 ** @modified $Date: 2011/10/23 20:09:49 $ by $Author: mks $
9 **
10 ** This library is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU Lesser General Public
12 ** License as published by the Free Software Foundation; either
13 ** version 2.1 of the License, or (at your option) any later version.
14 **
15 ** This library is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ** Lesser General Public License for more details.
19 **
20 ** You should have received a copy of the GNU Lesser General Public
21 ** License along with this library; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 ** MA  02110-1301,  USA.
24 **
25 ******************************************************************************/
26 
27 /* ========================================================================= */
28 /* ============================= include files ============================= */
29 /* ========================================================================= */
30 
31 #include "ajmem.h"
32 #include "ajassert.h"
33 #include "ajexcept.h"
34 #include "ajmess.h"
35 #include "ajutil.h"
36 
37 #include <stddef.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #ifdef HAVE_MCHECK
43 #include <mcheck.h>
44 #endif /* HAVE_MCHECK */
45 
46 
47 
48 
49 /* ========================================================================= */
50 /* =============================== constants =============================== */
51 /* ========================================================================= */
52 
53 
54 
55 
56 /* ========================================================================= */
57 /* =========================== global variables ============================ */
58 /* ========================================================================= */
59 
60 
61 
62 
63 /* ========================================================================= */
64 /* ============================= private data ============================== */
65 /* ========================================================================= */
66 
67 
68 
69 
70 /* ========================================================================= */
71 /* =========================== private constants =========================== */
72 /* ========================================================================= */
73 
74 
75 
76 
77 /* @conststatic Mem_Failed ****************************************************
78 **
79 ** Exception for "Allocation failed, insufficient memory available"
80 **
81 ******************************************************************************/
82 static const Except_T Mem_Failed =
83 {
84     "Allocation failed, insufficient memory available"
85 };
86 
87 
88 
89 
90 
91 /* @conststatic Mem_Badcount **************************************************
92 **
93 ** Exception for "Allocation bad byte count"
94 **
95 ******************************************************************************/
96 static const Except_T Mem_Badcount =
97 {
98     "Allocation bad byte count"
99 };
100 
101 
102 
103 
104 /* ========================================================================= */
105 /* =========================== private variables =========================== */
106 /* ========================================================================= */
107 
108 #ifdef AJ_SAVESTATS
109 static ajlong memAlloc       = 0;
110 static ajlong memFree        = 0;
111 static ajlong memCount       = 0;
112 static ajlong memResize      = 0;
113 static ajlong memResizeOld   = 0;
114 static ajlong memResizeCount = 0;
115 static ajlong memTotal       = 0;
116 static ajlong memZero        = 0;
117 #endif /* AJ_SAVESTATS */
118 
119 #ifdef HAVE_MCHECK
120 static void* probePtr = NULL;
121 static ajint probeLine = 0;
122 static const char* probeFile = "";
123 static AjBool probeTest = AJFALSE;
124 static ajint probeFail = 0;
125 static ajint probeMaxFail = 0;
126 #endif /* HAVE_MCHECK */
127 
128 
129 
130 
131 /* ========================================================================= */
132 /* =========================== private functions =========================== */
133 /* ========================================================================= */
134 
135 
136 
137 
138 /* ========================================================================= */
139 /* ======================= All functions by section ======================== */
140 /* ========================================================================= */
141 
142 
143 
144 
145 /* @func ajMemAlloc ***********************************************************
146 **
147 ** Allocates memory using malloc, and fails with an error message if
148 ** unsuccessful.
149 **
150 ** @param [r] nbytes [size_t] Number of bytes required
151 ** @param [r] file [const char*] Source file name, generated by a macro.
152 ** @param [r] line [ajint] Source line number, generated by a macro.
153 ** @param [r] nofail [AjBool] If true, return with a NULL pointer when
154 **                            unable to allocate.
155 ** @return [void*] Successfully allocated memory, or NULL on failure.
156 **                            Normal behaviour is to
157 **                            raise an exception and fail, or if running
158 **                            with Java, to print to standard error
159 **                            and exit.
160 **
161 ** @release 1.0.0
162 ** @@
163 ******************************************************************************/
164 
ajMemAlloc(size_t nbytes,const char * file,ajint line,AjBool nofail)165 void* ajMemAlloc(size_t nbytes, const char* file, ajint line, AjBool nofail)
166 {
167     void *ptr;
168 
169 #ifdef HAVE_JAVA
170     (void) file;                /* make it used */
171     (void) line;                /* make it used */
172 #endif /* HAVE_JAVA */
173 
174     if(nbytes <= 0)
175     {
176 #ifdef HAVE_JAVA
177 	fprintf(stderr,"Attempt to allocate <=0 bytes");
178 	exit(-1);
179 #else /* !HAVE_JAVA */
180 	ajExceptRaise(&Mem_Badcount, file, line);
181 #endif /* !HAVE_JAVA */
182     }
183 
184     ptr = malloc(nbytes);
185 
186     if(ptr == NULL)
187     {
188 	if (nofail)
189 	    return NULL;
190 #ifdef HAVE_JAVA
191 	fprintf(stderr,"Memory allocation failed in ajMemAlloc");
192 	exit(-1);
193 #else /* !HAVE_JAVA */
194 	if(file == NULL)
195 	    AJRAISE(Mem_Failed);
196 	else
197 	    ajExceptRaise(&Mem_Failed, file, line);
198 #endif /* !HAVE_JAVA */
199     }
200 
201 #ifdef AJ_SAVESTATS
202     memAlloc += nbytes;
203     memCount++;
204     memTotal++;
205 #endif /* AJ_SAVESTATS */
206 
207     return ptr;
208 }
209 
210 
211 
212 
213 /* @func ajMemCalloc **********************************************************
214 **
215 ** Allocates memory using calloc for an array of elements,
216 ** and fails with an error message if unsuccessful.
217 **
218 ** @param [r] count [size_t] Number of elements required
219 ** @param [r] nbytes [size_t] Number of bytes required per element
220 ** @param [r] file [const char*] Source file name, generated by a macro.
221 ** @param [r] line [ajint] Source line number, generated by a macro.
222 ** @param [r] nofail [AjBool] If true, return with a NULL pointer when
223 **                            unable to allocate.
224 ** @return [void*] Successfully allocated memory, or NULL on failure.
225 **                            Normal behaviour is to
226 **                            raise an exception and fail, or if running
227 **                            with Java, to print to standard error
228 **                            and exit.
229 **
230 ** @release 1.0.0
231 ** @@
232 ******************************************************************************/
233 
ajMemCalloc(size_t count,size_t nbytes,const char * file,ajint line,AjBool nofail)234 void* ajMemCalloc(size_t count, size_t nbytes,
235 		  const char* file, ajint line, AjBool nofail)
236 {
237     void *ptr;
238     size_t ibytes = nbytes;
239     size_t icount = count;
240 
241 #ifdef HAVE_JAVA
242     (void) file;                /* make it used */
243     (void) line;                /* make it used */
244 #endif /* HAVE_JAVA */
245 
246     if(count <= 0)
247         ajUtilCatch();
248 
249     if(!count)
250        icount = 1;
251     if(!nbytes)
252         ibytes = 1;
253 
254     ptr = calloc(icount, ibytes);
255 
256     if(ptr == NULL)
257     {
258 	if (nofail)
259 	    return NULL;
260 #ifdef HAVE_JAVA
261 	fprintf(stderr,"Memory allocation failed in ajMemCalloc");
262 	exit(-1);
263 #else /* !HAVE_JAVA */
264 	if(file == NULL)
265 	    AJRAISE(Mem_Failed);
266 	else
267 	    ajExceptRaise(&Mem_Failed, file, line);
268 #endif /* !HAVE_JAVA */
269     }
270 
271 #ifdef AJ_SAVESTATS
272     memAlloc += (icount*ibytes);
273     memCount++;
274     memTotal++;
275 #endif /* AJ_SAVESTATS */
276 
277     return ptr;
278 }
279 
280 
281 
282 
283 /* @func ajMemCallocZero ******************************************************
284 **
285 ** Allocates memory using calloc for an array of elements,
286 ** and fails with an error message if unsuccessful.
287 **
288 ** The memory is initialised to zero. This should be done by the standard
289 ** calloc function. It is explicitly done here to make sure.
290 **
291 ** @param [r] count [size_t] Number of elements required
292 ** @param [r] nbytes [size_t] Number of bytes required
293 ** @param [r] file [const char*] Source file name, generated by a macro.
294 ** @param [r] line [ajint] Source line number, generated by a macro.
295 ** @param [r] nofail [AjBool] If true, return with a NULL pointer when
296 **                            unable to allocate.
297 ** @return [void*] Successfully allocated memory, or NULL on failure.
298 **                            Normal behaviour is to
299 **                            raise an exception and fail, or if running
300 **                            with Java, to print to standard error
301 **                            and exit.
302 **
303 ** @release 6.0.0
304 ** @@
305 ******************************************************************************/
306 
ajMemCallocZero(size_t count,size_t nbytes,const char * file,ajint line,AjBool nofail)307 void* ajMemCallocZero(size_t count, size_t nbytes,
308 		      const char* file, ajint line, AjBool nofail)
309 {
310     void *ptr;
311     size_t ibytes = nbytes;
312     size_t icount = count;
313 
314 #ifdef HAVE_JAVA
315     (void) file;                /* make it used */
316     (void) line;                /* make it used */
317 #endif /* HAVE_JAVA */
318 
319     if(count <= 0)
320         ajUtilCatch();
321 
322     if(!count)
323        icount = 1;
324     if(!nbytes)
325         ibytes = 1;
326 
327     ptr = calloc(icount, ibytes);
328 
329     if(ptr == NULL)
330     {
331 	if (nofail)
332 	    return NULL;
333 #ifdef HAVE_JAVA
334 	fprintf(stderr,"Memory allocation failed in ajMemCallocZero");
335 	exit(-1);
336 #else /* !HAVE_JAVA */
337 	if(file == NULL)
338 	    AJRAISE(Mem_Failed);
339 	else
340 	    ajExceptRaise(&Mem_Failed, file, line);
341 #endif /* !HAVE_JAVA */
342     }
343 
344     memset(ptr, 0, icount*ibytes);
345 
346 #ifdef AJ_SAVESTATS
347     memAlloc += (icount*ibytes);
348     memCount++;
349     memTotal++;
350     memZero += (icount*ibytes);
351 #endif /* AJ_SAVESTATS */
352 
353     return ptr;
354 }
355 
356 
357 
358 
359 /* @func ajMemSetZero *********************************************************
360 **
361 ** Zeroes memory for an array of elements,
362 **
363 ** @param [u] ptr [void*] Pointer to memory previously allocated with 'malloc'
364 ** @param [r] count [size_t] Number of elements required
365 ** @param [r] nbytes [size_t] Number of bytes required
366 ** @return [void]
367 **
368 ** @release 6.0.0
369 ** @@
370 ******************************************************************************/
371 
ajMemSetZero(void * ptr,size_t count,size_t nbytes)372 void ajMemSetZero(void* ptr, size_t count, size_t nbytes)
373 {
374     if (ptr == NULL)
375 	return;
376 
377     if(!nbytes)
378         return;
379 
380     if(!count)
381         return;
382 
383     memset(ptr, 0, count*nbytes);
384 
385 #ifdef AJ_SAVESTATS
386     memZero += (count*nbytes);
387 #endif /* AJ_SAVESTATS */
388 
389     return;
390 }
391 
392 
393 
394 
395 /* @func ajMemFree ************************************************************
396 **
397 ** Frees memory using 'free' and zeroes the pointer. Ignores NULL
398 ** (uninitialised) pointers.
399 **
400 ** @param [u] ptr [void**] Pointer to memory previously allocated with 'malloc'
401 **
402 ** @release 1.0.0
403 ** @@
404 ******************************************************************************/
405 
ajMemFree(void ** ptr)406 void ajMemFree(void** ptr)
407 {
408     if(!ptr)
409         return;
410     if(!*ptr)
411         return;
412 
413     free(*ptr);
414     *ptr = NULL;
415 
416 #ifdef AJ_SAVESTATS
417     memCount--;
418     memFree++;
419 #endif /* AJ_SAVESTATS */
420 
421     return;
422 }
423 
424 
425 
426 
427 /* @func ajMemResize **********************************************************
428 **
429 ** Resizes previously allocated memory, and ensures data is copied to
430 ** the new location if it is moved.
431 **
432 ** If the pointer is new then new memory is allocated automatically.
433 **
434 ** The C run-time library function realloc does preserve existing values
435 ** but does not initialise any memory after the old contents.
436 **
437 ** @param [u] ptr [void*] Pointer to memory previously allocated with 'malloc'
438 ** @param [r] nbytes [size_t] Number of bytes required
439 ** @param [r] file [const char*] Source file name, generated by a macro.
440 ** @param [r] line [ajint] Source line number, generated by a macro.
441 ** @param [r] nofail [AjBool] If true, return with a NULL pointer when
442 **                            unable to allocate.
443 ** @return [void*] Successfully reallocated memory, or NULL on failure.
444 **                            Normal behaviour is to
445 **                            raise an exception and fail, or if running
446 **                            with Java, to print to standard error
447 **                            and exit.
448 **
449 ** @release 1.0.0
450 ** @@
451 ******************************************************************************/
452 
ajMemResize(void * ptr,size_t nbytes,const char * file,ajint line,AjBool nofail)453 void* ajMemResize(void* ptr, size_t nbytes,
454 		  const char* file, ajint line, AjBool nofail)
455 {
456     size_t ibytes = nbytes;
457 
458     if(!nbytes)
459         ibytes = 1;
460 
461     if(ptr == NULL)
462     {
463 	ptr = ajMemCallocZero(ibytes, 1, file, line, nofail);
464 
465 	return ptr;
466     }
467 
468     ptr = realloc(ptr, ibytes);
469 
470     if(ptr == NULL)
471     {
472 	if (nofail)
473 	    return NULL;
474 #ifdef HAVE_JAVA
475 	fprintf(stderr,"Memory allocation failed in ajMemResize");
476 	exit(-1);
477 #else /* !HAVE_JAVA */
478 	if(file == NULL)
479 	    AJRAISE(Mem_Failed);
480 	else
481 	    ajExceptRaise(&Mem_Failed, file, line);
482 #endif /* !HAVE_JAVA */
483     }
484 
485 #ifdef AJ_SAVESTATS
486     memResize += ibytes;
487     memResizeCount++;
488 #endif /* AJ_SAVESTATS */
489 
490     return ptr;
491 }
492 
493 
494 
495 
496 /* @func ajMemResizeZero ******************************************************
497 **
498 ** Resizes previously allocated memory, and ensures data is copied to
499 ** the new location if it is moved.
500 **
501 ** If the pointer is new then new memory is allocated automatically.
502 **
503 ** Memory beyond the previous contents is initialised to zero
504 **
505 ** The C run-time library function realloc does preserves existing values
506 ** but does not initialise any memory after the old contents. This is why
507 ** this function needs to be told what the old size was.
508 **
509 ** @param [u] ptr [void*] Pointer to memory previously allocated with 'malloc'
510 ** @param [r] oldbytes [size_t] Number of bytes required
511 ** @param [r] nbytes [size_t] Number of bytes required
512 ** @param [r] file [const char*] Source file name, generated by a macro.
513 ** @param [r] line [ajint] Source line number, generated by a macro.
514 ** @param [r] nofail [AjBool] If true, return with a NULL pointer when
515 **                            unable to allocate.
516 ** @return [void*] Successfully reallocated memory, or NULL on failure.
517 **                            Normal behaviour is to
518 **                            raise an exception and fail, or if running
519 **                            with Java, to print to standard error
520 **                            and exit.
521 **
522 ** @release 6.0.0
523 ** @@
524 ******************************************************************************/
525 
ajMemResizeZero(void * ptr,size_t oldbytes,size_t nbytes,const char * file,ajint line,AjBool nofail)526 void* ajMemResizeZero(void* ptr, size_t oldbytes, size_t nbytes,
527 		      const char* file, ajint line, AjBool nofail)
528 {
529     size_t ibytes = nbytes;
530 
531     if(!nbytes)
532         ibytes = 1;
533 
534     if(ptr == NULL)
535     {
536 	ptr = ajMemCallocZero(ibytes, 1, file, line, nofail);
537 
538 	return ptr;
539     }
540 
541     ptr = realloc(ptr, ibytes);
542 
543     if(ptr == NULL)
544     {
545 	if (nofail)
546 	    return NULL;
547 #ifdef HAVE_JAVA
548 	fprintf(stderr,"Memory allocation failed in ajMemResizeZero");
549 	exit(-1);
550 #else /* !HAVE_JAVA */
551 	if(file == NULL)
552 	    AJRAISE(Mem_Failed);
553 	else
554 	    ajExceptRaise(&Mem_Failed, file, line);
555 #endif /* !HAVE_JAVA */
556     }
557 
558     if(ibytes > oldbytes)
559 	memset(((char*)ptr)+oldbytes, 0, (nbytes-oldbytes));
560 
561 #ifdef AJ_SAVESTATS
562     memResizeOld += oldbytes;
563     memResize += ibytes;
564     memResizeCount++;
565 #endif /* AJ_SAVESTATS */
566 
567     return ptr;
568 }
569 
570 
571 
572 
573 /* @func ajMemArrB ************************************************************
574 **
575 ** Creates an AjBool array.
576 ** Use AJFREE to free the memory when no longer needed.
577 **
578 ** @param [r] size [size_t] Number of array elements.
579 ** @return [ajint*] Newly allocated array.
580 **
581 ** @release 1.0.0
582 ** @@
583 ******************************************************************************/
584 
ajMemArrB(size_t size)585 ajint* ajMemArrB(size_t size)
586 {
587     return AJCALLOC(size, sizeof(AjBool));
588 }
589 
590 
591 
592 
593 /* @func ajMemArrI ************************************************************
594 **
595 ** Creates an integer array.
596 ** Use AJFREE to free the memory when no longer needed.
597 **
598 ** @param [r] size [size_t] Number of array elements.
599 ** @return [ajint*] Newly allocated array.
600 **
601 ** @release 1.0.0
602 ** @@
603 ******************************************************************************/
604 
ajMemArrI(size_t size)605 ajint* ajMemArrI(size_t size)
606 {
607     return AJCALLOC(size, sizeof(ajint));
608 }
609 
610 
611 
612 
613 /* @func ajMemArrF ************************************************************
614 **
615 ** Creates a float array.
616 ** Use AJFREE to free the memory when no longer needed.
617 **
618 ** @param [r] size [size_t] Number of array elements.
619 ** @return [float*] Newly allocated array.
620 **
621 ** @release 1.0.0
622 ** @@
623 ******************************************************************************/
624 
ajMemArrF(size_t size)625 float* ajMemArrF(size_t size)
626 {
627     return AJCALLOC(size, sizeof(float));
628 }
629 
630 
631 
632 
633 /* @func ajMemStat ************************************************************
634 **
635 ** Prints a summary of memory usage with debug calls
636 **
637 ** @param [r] title [const char*] Title for this summary
638 ** @return [void]
639 **
640 ** @release 1.0.0
641 ** @@
642 ******************************************************************************/
643 
ajMemStat(const char * title)644 void ajMemStat(const char* title)
645 {
646 #ifdef AJ_SAVESTATS
647     static ajlong statAlloc       = 0;
648     static ajlong statCount       = 0;
649     static ajlong statFree        = 0;
650     static ajlong statResize      = 0;
651     static ajlong statResizeOld   = 0;
652     static ajlong statResizeCount = 0;
653     static ajlong statTotal       = 0;
654     static ajlong statZero        = 0;
655 
656     ajDebug("Memory usage since last call %s:\n", title);
657     ajDebug("Memory usage (bytes): %Ld allocated, %Ld reallocated "
658 	    "%Ld returned %Ld zeroed\n",
659 	    memAlloc - statAlloc, memResize - statResize,
660 	    memResizeOld - statResizeOld, memZero - statZero);
661     ajDebug("Memory usage (number): %Ld allocates, "
662 	    "%Ld frees, %Ld resizes, %Ld in use\n",
663 	    memTotal - statTotal, memFree - statFree,
664 	    memResizeCount - statResizeCount, memCount - statCount);
665 
666     statAlloc  = memAlloc;
667     statCount  = memCount;
668     statFree   = memFree;
669     statResize = memResize;
670     statTotal  = memTotal;
671     statZero   = memZero;
672 
673     statResizeCount = memResizeCount;
674 #else /* !AJ_SAVESTATS */
675     (void) title;               /* make it used */
676 #endif /* !AJ_SAVESTATS */
677 
678     return;
679 }
680 
681 
682 
683 
684 /* @func ajMemExit ************************************************************
685 **
686 ** Prints a summary of memory usage with debug calls
687 **
688 ** @return [void]
689 **
690 ** @release 1.0.0
691 ** @@
692 ******************************************************************************/
693 
ajMemExit(void)694 void ajMemExit(void)
695 {
696 #ifdef AJ_SAVESTATS
697     ajDebug("Memory usage (bytes): %Ld allocated, %Ld reallocated "
698 	    "%Ld returned %Ld zeroed\n",
699 	    memAlloc, memResize,memResizeOld,  memZero);
700     ajDebug("Memory usage (number): %Ld allocates, "
701 	    "%Ld frees, %Ld resizes, %Ld in use\n",
702 	    memTotal, memFree, memResizeCount, memCount);
703 #endif /* AJ_SAVESTATS */
704 
705     return;
706 }
707 
708 
709 
710 
711 /* @func ajMemCheck ***********************************************************
712 **
713 ** Prints a message appropriate to the memcheck status
714 **
715 ** @param [r] istat [int] Enumerated value from mprobe
716 ** @return [void]
717 **
718 ** @release 6.0.0
719 ** @@
720 ******************************************************************************/
ajMemCheck(int istat)721 void ajMemCheck(int istat)
722 {
723 #ifdef HAVE_MCHECK
724     if(probeTest)
725     {
726 	if(istat == MCHECK_OK)
727 	    ajWarn("ajMemProbe called for %x in %s line %d",
728 		   probePtr, probeFile, probeLine);
729 	else
730 	    ajErr("ajMemProbe called for %x in %s line %d",
731 		  probePtr, probeFile, probeLine);
732     }
733 
734     if(istat == MCHECK_DISABLED)
735 	ajUser("mcheck is disabled\n");
736     else if(istat == MCHECK_OK)
737 	ajUser("mcheck OK\n");
738     else if(istat == MCHECK_HEAD)
739 	ajUser("mcheck data before was modified\n");
740     else if(istat == MCHECK_TAIL)
741 	ajUser("mcheck data after was modified\n");
742     else if(istat == MCHECK_FREE)
743 	ajUser("mcheck data already freed\n");
744     else
745 	ajUser("mcheck ... SOMETHING UNEXPECTED\n");
746 
747 
748     if(probeMaxFail && (++probeFail >= probeMaxFail))
749        ajDie("Maximum ajMemProbe failures %d", probeFail);
750 #else /* !HAVE_MCHECK */
751     (void) istat;
752 #endif /* !HAVE_MCHECK */
753 
754     return;
755 }
756 
757 
758 
759 
760 /* @func ajMemCheckSetLimit ***************************************************
761 **
762 ** Prints a message appropriate to the memcheck status
763 **
764 ** @param [r] maxfail [ajint] Maximum failures allowed
765 ** @return [void]
766 **
767 ** @release 6.0.0
768 ** @@
769 ******************************************************************************/
ajMemCheckSetLimit(ajint maxfail)770 void ajMemCheckSetLimit(ajint maxfail)
771 {
772 #ifdef HAVE_MCHECK
773     if(probeFail >= maxfail)
774       ajDie("Maximum ajMemProbe failures set to %d, already at %d",
775 	    maxfail, probeFail);
776 
777     probeMaxFail = maxfail;
778 #else /* !HAVE_MCHECK */
779     (void) maxfail;
780 #endif /* !HAVE_MCHECK */
781 
782     return;
783 }
784 
785 
786 
787 
788 /* @func ajMemProbe ***********************************************************
789 **
790 ** Probes a memory location for possible errors
791 **
792 ** @param [u] ptr [void*] Pointer to memory previously allocated with 'malloc'
793 ** @param [r] file [const char*] Source file name, generated by a macro.
794 ** @param [r] line [ajint] Source line number, generated by a macro.
795 ** @return [void]
796 **
797 ** @release 6.0.0
798 ** @@
799 ******************************************************************************/
800 
ajMemProbe(void * ptr,const char * file,ajint line)801 void ajMemProbe(void* ptr,
802 		const char* file, ajint line)
803 {
804 #ifdef HAVE_MCHECK
805     if(ptr == NULL)
806     {
807 	ajWarn("ajMemProbe address %x NULL in %s at line %d", ptr, file, line);
808 
809 	return;
810     }
811 
812     probeLine = line;
813     probeFile = file;
814     probeTest = ajTrue;
815     probePtr = ptr;
816 
817     mprobe(ptr);
818 
819     probeTest = ajFalse;
820 #else /* !HAVE_MCHECK */
821     (void) ptr;
822     (void) file;
823     (void) line;
824 #endif /* !HAVE_MCHECK */
825 
826     return;
827 }
828 
829 
830 
831 
832 #ifdef AJ_COMPILE_DEPRECATED_BOOK
833 #endif
834 
835 
836 
837 
838 #ifdef AJ_COMPILE_DEPRECATED
839 /* @obsolete ajMemCalloc0
840 ** @rename ajMemCallocZero
841 */
842 
ajMemCalloc0(size_t count,size_t nbytes,const char * file,ajint line,AjBool nofail)843 __deprecated void* ajMemCalloc0(size_t count, size_t nbytes,
844 				   const char* file, ajint line, AjBool nofail)
845 {
846   return ajMemCallocZero(count, nbytes, file, line, nofail);
847 }
848 
849 #endif
850