默认情况下,libevent使用C库的内存管理函数在堆上分配内存。通过提供malloc、realloc和free的替代函数,可以让libevent使用其他的内存管理器。希望libevent使
用一个更高效的分配器时;或者希望libevent使用一个工具分配器,以便检查内存泄漏时,可能需要这样做。
接口
void event_set_mem_functions(void*(*malloc_fn)(size_t sz), void *(*realloc_fn)(void *ptr, size_tsz), void (*free_fn)(void *ptr));
注意:
1、替换内存管理函数影响libevent随后的所有分配、调整大小和释放内存操作。所以,必须保证在调用任何其他libevent函数之前进行替换。否则,libevent可能用你的free函数释放用C库的malloc分配的内存。
2、你的malloc和realloc函数返回的内存块应该具有和C库返回的内存块一样的地址对齐。
3、你的realloc函数应该正确处理realloc(NULL,sz)(也就是当作malloc(sz)处理),realloc函数应该正确处理realloc(ptr,0)(也就是当作free(ptr)处理)
4、你的free函数不必处理free(NULL)
5、你的malloc函数不必处理malloc(0)
6、如果在多个线程中使用libevent,替代的内存管理函数需要是线程安全的。
7、libevent将使用这些函数分配返回给你的内存。所以,如果要释放由libevent函数分配和返回的内存,而你已经替换malloc和realloc函数,那么应该使用替代的free函
数。
这里有个替换libevent分配器函数的示例,它可以计算已经分配的字节数。实际应用中可能需要添加锁,以避免运行在多个线程中时发生错误。
#include <event2/event.h> #include <sys/types.h> #include <stdlib.h> union alignment { size_t sz; void *ptr; double dbl; }; #define ALIGNMENT sizeof(union alignment) #define OUTPTR(ptr)(((char*)ptr)+ALIGNMENT) #define INPTR(ptr) (((char*)ptr)ALIGNMENT) static size_t total_allocated = 0; static void *replacement_malloc(size_t sz) { void *chunk = malloc(sz + ALIGNMENT); if (!chunk) return chunk; total_allocated += sz; *(size_t*)chunk = sz; return OUTPTR(chunk); } static void *replacement_realloc(void *ptr,size_t sz) { size_t old_size = 0; if (ptr) { ptr = INPTR(ptr); old_size = *(size_t*)ptr; } ptr = realloc(ptr, sz + ALIGNMENT); if (!ptr) return NULL; *(size_t*)ptr = sz; total_allocated = total_allocated old_ size + sz; return OUTPTR(ptr); } static void replacement_free(void *ptr) { ptr = INPTR(ptr); total_allocated = *(size_t*)ptr; free(ptr); } void start_counting_bytes(void) { event_set_mem_functions(replacement_malloc, replacement_realloc, replacement_free); }