libevent并没有实现特别的内存分配,仅仅是给使用者提供了内存分配的接口,当我们没有设置内存分配函数时(也就是这几个全局函数指针为空,
static void *(*_mm_malloc_fn)(size_t sz) = NULL; static void *(*_mm_realloc_fn)(void *p, size_t sz) = NULL; static void (*_mm_free_fn)(void *p) = NULL;),会相应的调用库函数malloc、calloc、free、strdup。
如:#define mm_malloc(sz) malloc(sz) #define mm_calloc(n, sz) calloc((n), (sz)) #define mm_strdup(s) strdup(s) #define mm_realloc(p, sz) realloc((p), (sz)) #define mm_free(p) free(p)
#ifndef _EVENT_MM_INTERNAL_H #define _EVENT_MM_INTERNAL_H #include <sys/types.h> #ifdef __cplusplus extern "C" { #endif #ifndef _EVENT_DISABLE_MM_REPLACEMENT//没有禁止用户使用自己的内存分配函数,就给用户提供接口 /* Internal use only: Memory allocation functions. We give them nice short * mm_names for our own use, but make sure that the symbols have longer names * so they don't conflict with other libraries (like, say, libmm). */
void *event_mm_malloc_(size_t sz); void *event_mm_calloc_(size_t count, size_t size); char *event_mm_strdup_(const char *s); void *event_mm_realloc_(void *p, size_t sz); void event_mm_free_(void *p); #define mm_malloc(sz) event_mm_malloc_(sz) #define mm_calloc(count, size) event_mm_calloc_((count), (size)) #define mm_strdup(s) event_mm_strdup_(s) #define mm_realloc(p, sz) event_mm_realloc_((p), (sz)) #define mm_free(p) event_mm_free_(p) #else//禁止用户使用自己的内存分配函数 #define mm_malloc(sz) malloc(sz) #define mm_calloc(n, sz) calloc((n), (sz)) #define mm_strdup(s) strdup(s) #define mm_realloc(p, sz) realloc((p), (sz)) #define mm_free(p) free(p) #endif #ifdef __cplusplus } #endif #endif
实际的实现代码在event.c中
void * event_mm_malloc_(size_t sz) { if (_mm_malloc_fn) return _mm_malloc_fn(sz); else return malloc(sz); } void * event_mm_calloc_(size_t count, size_t size) { if (_mm_malloc_fn) { size_t sz = count * size; void *p = _mm_malloc_fn(sz); if (p) memset(p, 0, sz); return p; } else return calloc(count, size); } char * event_mm_strdup_(const char *str) { if (_mm_malloc_fn) { size_t ln = strlen(str); void *p = _mm_malloc_fn(ln+1); if (p) memcpy(p, str, ln+1); return p; } else #ifdef WIN32 return _strdup(str); #else return strdup(str); #endif } void * event_mm_realloc_(void *ptr, size_t sz) { if (_mm_realloc_fn) return _mm_realloc_fn(ptr, sz); else return realloc(ptr, sz); } void event_mm_free_(void *ptr) { if (_mm_free_fn) _mm_free_fn(ptr); else free(ptr); } void event_set_mem_functions(void *(*malloc_fn)(size_t sz), void *(*realloc_fn)(void *ptr, size_t sz), void (*free_fn)(void *ptr)) { _mm_malloc_fn = malloc_fn; _mm_realloc_fn = realloc_fn; _mm_free_fn = free_fn; } #endif