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 /* NetHack may be freely redistributed. See license for details. */
5 /* to get the malloc() prototype from system.h */
6 #define ALLOC_C /* comment line for pre-compiled headers */
7 /* since this file is also used in auxiliary programs, don't include all the
8 function declarations for all of nethack */
9 #define EXTERN_H /* comment line for pre-compiled headers */
12 char *FDECL(fmt_ptr
, (const genericptr
));
17 extern void FDECL(free
, (genericptr_t
));
18 static void NDECL(heapmon_init
);
20 static FILE *heaplog
= 0;
21 static boolean tried_heaplog
= FALSE
;
24 long *FDECL(alloc
, (unsigned int));
25 extern void VDECL(panic
, (const char *, ...)) PRINTF_F(1, 2);
29 register unsigned int lth
;
33 * a ridiculous definition, suppressing
34 * "possible pointer alignment problem" for (long *) malloc()
37 long dummy
= ftell(stderr
);
40 dummy
= 0; /* make sure arg is used */
43 register genericptr_t ptr
;
48 panic("Memory allocation failure; cannot get %u bytes", lth
);
56 #define PTR_TYP genericptr_t
58 #define PTR_FMT "%06lx"
59 #define PTR_TYP unsigned long
62 /* A small pool of static formatting buffers.
63 * PTRBUFSIZ: We assume that pointers will be formatted as integers in
64 * hexadecimal, requiring at least 16+1 characters for each buffer to handle
65 * 64-bit systems, but the standard doesn't mandate that encoding and an
66 * implementation could do something different for %p, so we make some
68 * PTRBUFCNT: Number of formatted values which can be in use at the same
69 * time. To have more, callers need to make copies of them as they go.
73 static char ptrbuf
[PTRBUFCNT
][PTRBUFSIZ
];
74 static int ptrbufidx
= 0;
76 /* format a pointer for display purposes; returns a static buffer */
83 buf
= ptrbuf
[ptrbufidx
];
84 if (++ptrbufidx
>= PTRBUFCNT
)
87 Sprintf(buf
, PTR_FMT
, (PTR_TYP
) ptr
);
93 /* If ${NH_HEAPLOG} is defined and we can create a file by that name,
94 then we'll log the allocation and release information to that file. */
98 char *logname
= getenv("NH_HEAPLOG");
100 if (logname
&& *logname
)
101 heaplog
= fopen(logname
, "w");
102 tried_heaplog
= TRUE
;
106 nhalloc(lth
, file
, line
)
111 long *ptr
= alloc(lth
);
116 (void) fprintf(heaplog
, "+%5u %s %4d %s\n", lth
,
117 fmt_ptr((genericptr_t
) ptr
), line
, file
);
118 /* potential panic in alloc() was deferred til here */
120 panic("Cannot get %u bytes, line %d of %s", lth
, line
, file
);
126 nhfree(ptr
, file
, line
)
134 (void) fprintf(heaplog
, "- %s %4d %s\n",
135 fmt_ptr((genericptr_t
) ptr
), line
, file
);
140 /* strdup() which uses our alloc() rather than libc's malloc(),
141 with caller tracking */
143 nhdupstr(string
, file
, line
)
148 return strcpy((char *) nhalloc(strlen(string
) + 1, file
, line
), string
);
152 #endif /* MONITOR_HEAP */
154 /* strdup() which uses our alloc() rather than libc's malloc();
155 not used when MONITOR_HEAP is enabled, but included unconditionally
156 in case utility programs get built using a different setting for that */
161 return strcpy((char *) alloc(strlen(string
) + 1), string
);