summaryrefslogtreecommitdiff
path: root/src/common/memmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/memmgr.c')
-rw-r--r--src/common/memmgr.c99
1 files changed, 81 insertions, 18 deletions
diff --git a/src/common/memmgr.c b/src/common/memmgr.c
index 97991ceaa..15e55fbeb 100644
--- a/src/common/memmgr.c
+++ b/src/common/memmgr.c
@@ -45,7 +45,7 @@ struct malloc_interface *iMalloc;
# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line))
# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line))
# define FREE(p,file,line,func) mwFree((p),(file),(line))
-# define MEMORY_USAGE() (size_t)0
+# define MEMORY_USAGE() ((size_t)0)
# define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1)
# define MEMORY_CHECK() CHECK()
@@ -67,21 +67,21 @@ struct malloc_interface *iMalloc;
# include <gc.h>
# ifdef GC_ADD_CALLER
-# define RETURN_ADDR 0,
+# define MALLOC(n,file,line,func) GC_debug_malloc((n), 0, (file), (line))
+# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), 0, (file), (line))
+# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), 0, (file), (line))
+# define STRDUP(p,file,line,func) GC_debug_strdup((p), 0, (file), (line))
# else
-# define RETURN_ADDR
+# define MALLOC(n,file,line,func) GC_debug_malloc((n), (file), (line))
+# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), (file), (line))
+# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), (file), (line))
+# define STRDUP(p,file,line,func) GC_debug_strdup((p), (file), (line))
# endif
-# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line))
-# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line))
-# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line))
-# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line))
# define FREE(p,file,line,func) GC_debug_free(p)
# define MEMORY_USAGE() GC_get_heap_size()
# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL)
# define MEMORY_CHECK() GC_gcollect()
-# undef RETURN_ADDR
-
#else
# define MALLOC(n,file,line,func) malloc(n)
@@ -89,18 +89,18 @@ struct malloc_interface *iMalloc;
# define REALLOC(p,n,file,line,func) realloc((p),(n))
# define STRDUP(p,file,line,func) strdup(p)
# define FREE(p,file,line,func) free(p)
-# define MEMORY_USAGE() (size_t)0
+# define MEMORY_USAGE() ((size_t)0)
# define MEMORY_VERIFY(ptr) true
-# define MEMORY_CHECK()
+# define MEMORY_CHECK() (void)0
#endif
#ifndef USE_MEMMGR
-#ifdef __APPLE__
+#if defined __APPLE__
#include <malloc/malloc.h>
#define BUFFER_SIZE(ptr) malloc_size(ptr)
-#elif __FreeBSD__
+#elif defined __FreeBSD__
#include <malloc_np.h>
#define BUFFER_SIZE(ptr) malloc_usable_size(ptr)
#elif defined __linux__ || defined __linux || defined CYGWIN
@@ -149,7 +149,7 @@ void* aRealloc_(void *p, size_t size, const char *file, int line, const char *fu
void* aReallocz_(void *p, size_t size, const char *file, int line, const char *func)
{
- void *ret;
+ unsigned char *ret = NULL;
// ShowMessage("%s:%d: in func %s: aReallocz %p %ld\n",file,line,func,p,size);
#ifdef USE_MEMMGR
ret = REALLOC(p, size, file, line, func);
@@ -159,11 +159,11 @@ void* aReallocz_(void *p, size_t size, const char *file, int line, const char *f
size_t oldSize = BUFFER_SIZE(p);
ret = REALLOC(p, size, file, line, func);
newSize = BUFFER_SIZE(ret);
- if (ret && newSize > oldSize)
+ if (ret != NULL && newSize > oldSize)
memset(ret + oldSize, 0, newSize - oldSize);
} else {
ret = REALLOC(p, size, file, line, func);
- if (ret)
+ if (ret != NULL)
memset(ret, 0, BUFFER_SIZE(ret));
}
#endif
@@ -184,6 +184,36 @@ char* aStrdup_(const char *p, const char *file, int line, const char *func)
}
return ret;
}
+
+/**
+ * Copies a string to a newly allocated buffer, setting a maximum length.
+ *
+ * The string is always NULL-terminated. If the string is longer than `size`,
+ * then `size` bytes are copied, not including the appended NULL terminator.
+ *
+ * @warning
+ * If malloc is out of memory, throws a fatal error and aborts the program.
+ *
+ * @param p the source string to copy.
+ * @param size The maximum string length to copy.
+ * @param file @see ALC_MARK.
+ * @param line @see ALC_MARK.
+ * @param func @see ALC_MARK.
+ * @return the copied string.
+ */
+char *aStrndup_(const char *p, size_t size, const char *file, int line, const char *func)
+{
+ size_t len = strnlen(p, size);
+ char *ret = MALLOC(len + 1, file, line, func);
+ if (ret == NULL) {
+ ShowFatalError("%s:%d: in func %s: aStrndup error out of memory!\n", file, line, func);
+ exit(EXIT_FAILURE);
+ }
+ memcpy(ret, p, len);
+ ret[len] = '\0';
+ return ret;
+}
+
void aFree_(void *p, const char *file, int line, const char *func)
{
// ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p);
@@ -305,7 +335,7 @@ void *mmalloc_(size_t size, const char *file, int line, const char *func) {
struct unit_head *head;
if (((long) size) < 0) {
- ShowError("mmalloc_: %"PRIdS"\n", size);
+ ShowError("mmalloc_: %"PRIuS"\n", size);
return NULL;
}
@@ -478,6 +508,37 @@ char *mstrdup_(const char *p, const char *file, int line, const char *func) {
}
}
+/**
+ * Copies a string to a newly allocated buffer, setting a maximum length.
+ *
+ * The string is always NULL-terminated. If the string is longer than `size`,
+ * then `size` bytes are copied, not including the appended NULL terminator.
+ *
+ * @warning
+ * If malloc is out of memory, throws a fatal error and aborts the program.
+ *
+ * @param p the source string to copy.
+ * @param size The maximum string length to copy.
+ * @param file @see ALC_MARK.
+ * @param line @see ALC_MARK.
+ * @param func @see ALC_MARK.
+ * @return the copied string.
+ * @retval NULL if the source string is NULL or in case of error.
+ */
+char *mstrndup_(const char *p, size_t size, const char *file, int line, const char *func)
+{
+ if (p == NULL) {
+ return NULL;
+ } else {
+ size_t len = strnlen(p, size);
+ char *string = iMalloc->malloc(len + 1, file, line, func);
+ memcpy(string, p, len);
+ string[len] = '\0';
+ return string;
+ }
+}
+
+
void mfree_(void *ptr, const char *file, int line, const char *func) {
struct unit_head *head;
@@ -820,7 +881,7 @@ void memmgr_report (int extra) {
}
for( j = 0; j < 100; j++ ) {
if( data[j].size != 0 ) {
- ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024);
+ ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %u instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024);
}
}
ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024);
@@ -947,6 +1008,7 @@ void malloc_defaults(void) {
iMalloc->realloc = mrealloc_;
iMalloc->reallocz = mreallocz_;
iMalloc->astrdup = mstrdup_;
+ iMalloc->astrndup = mstrndup_;
iMalloc->free = mfree_;
#else
iMalloc->malloc = aMalloc_;
@@ -954,6 +1016,7 @@ void malloc_defaults(void) {
iMalloc->realloc = aRealloc_;
iMalloc->reallocz = aReallocz_;/* not using memory manager huhum o.o perhaps we could still do something about */
iMalloc->astrdup = aStrdup_;
+ iMalloc->astrndup = aStrndup_;
iMalloc->free = aFree_;
#endif
iMalloc->post_shutdown = NULL;