1 /* NetHack 3.6 alloc.c $NHDT-Date: 1454376505 2016/02/02 01:28:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* to get the malloc() prototype from system.h */
7 #define ALLOC_C /* comment line for pre-compiled headers */
8 /* since this file is also used in auxiliary programs, don't include all the
9 function declarations for all of nethack */
10 #define EXTERN_H /* comment line for pre-compiled headers */
13 char *FDECL(fmt_ptr, (const genericptr));
18 extern void FDECL(free, (genericptr_t));
19 static void NDECL(heapmon_init);
21 static FILE *heaplog = 0;
22 static boolean tried_heaplog = FALSE;
25 long *FDECL(alloc, (unsigned int));
26 extern void VDECL(panic, (const char *, ...)) PRINTF_F(1, 2);
30 register unsigned int lth;
34 * a ridiculous definition, suppressing
35 * "possible pointer alignment problem" for (long *) malloc()
38 long dummy = ftell(stderr);
41 dummy = 0; /* make sure arg is used */
44 register genericptr_t ptr;
49 panic("Memory allocation failure; cannot get %u bytes", lth);
57 #define PTR_TYP genericptr_t
59 #define PTR_FMT "%06lx"
60 #define PTR_TYP unsigned long
63 /* A small pool of static formatting buffers.
64 * PTRBUFSIZ: We assume that pointers will be formatted as integers in
65 * hexadecimal, requiring at least 16+1 characters for each buffer to handle
66 * 64-bit systems, but the standard doesn't mandate that encoding and an
67 * implementation could do something different for %p, so we make some
69 * PTRBUFCNT: Number of formatted values which can be in use at the same
70 * time. To have more, callers need to make copies of them as they go.
74 static char ptrbuf[PTRBUFCNT][PTRBUFSIZ];
75 static int ptrbufidx = 0;
77 /* format a pointer for display purposes; returns a static buffer */
84 buf = ptrbuf[ptrbufidx];
85 if (++ptrbufidx >= PTRBUFCNT)
88 Sprintf(buf, PTR_FMT, (PTR_TYP) ptr);
94 /* If ${NH_HEAPLOG} is defined and we can create a file by that name,
95 then we'll log the allocation and release information to that file. */
99 char *logname = getenv("NH_HEAPLOG");
101 if (logname && *logname)
102 heaplog = fopen(logname, "w");
103 tried_heaplog = TRUE;
107 nhalloc(lth, file, line)
112 long *ptr = alloc(lth);
117 (void) fprintf(heaplog, "+%5u %s %4d %s\n", lth,
118 fmt_ptr((genericptr_t) ptr), line, file);
119 /* potential panic in alloc() was deferred til here */
121 panic("Cannot get %u bytes, line %d of %s", lth, line, file);
127 nhfree(ptr, file, line)
135 (void) fprintf(heaplog, "- %s %4d %s\n",
136 fmt_ptr((genericptr_t) ptr), line, file);
141 /* strdup() which uses our alloc() rather than libc's malloc(),
142 with caller tracking */
144 nhdupstr(string, file, line)
149 return strcpy((char *) nhalloc(strlen(string) + 1, file, line), string);
153 #endif /* MONITOR_HEAP */
155 /* strdup() which uses our alloc() rather than libc's malloc();
156 not used when MONITOR_HEAP is enabled, but included unconditionally
157 in case utility programs get built using a different setting for that */
162 return strcpy((char *) alloc(strlen(string) + 1), string);