預設情況下,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);
}