diff options
Diffstat (limited to 'src/common/memmgr.c')
-rw-r--r-- | src/common/memmgr.c | 99 |
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; |