重写malloc时出现问题
我试图通过这样做来覆盖malloc。
#define malloc(X) my_malloc((X)) void* my_malloc(size_t size) { void *p = malloc(size); printf ("Allocated = %s, %s, %s, %x\n",__FILE__, __LINE__, __FUNCTION__, p); return p; }
但是,这是无限期地递归调用my_malloc(因为my_malloc中的malloc调用)。 我想在my_malloc中调用C malloc函数而不是宏实现。 你能告诉我怎么做吗?
谢谢。
问题解决了:
void* my_malloc(size_t size, const char *file, int line, const char *func) { void *p = malloc(size); printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size); return p; } #define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
使用Glibc , malloc_hook(3)
作为全局介入自己的malloc
函数的正确方法。
#include #include static void *(*old_malloc_hook)(size_t, const void *); static void *new_malloc_hook(size_t size, const void *caller) { void *mem; __malloc_hook = old_malloc_hook; mem = malloc(size); fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem); __malloc_hook = new_malloc_hook; return mem; } static void init_my_hooks(void) { old_malloc_hook = __malloc_hook; __malloc_hook = new_malloc_hook; } void (*__malloc_initialize_hook)(void) = init_my_hooks;
$ cat> mem.c <<'EOF' (上面的代码) EOF $ cat> main.c <<'EOF' #include#include int main(){ char * buf = malloc(50); sprintf(buf,“Hello,world!”); 放(BUF); 自由(BUF); 返回0; } EOF $ cc mem.c main.c $ ./a.out 0x40077e:malloc(50)= 0x22f7010 你好,世界!
(我们可以使用__attribute__((constructor))
,但这个技巧不是必需的:Glibc方便地提供__malloc_initialize_hook
作为在main
之前加载运行代码的另一种方法。)
修复两个宏替换问题,并使LINE等工作,因为你希望他们会:
#define malloc(X) my_malloc((X), __FILE__, __LINE__, __FUNCTION__) void* my_malloc(size_t size, const char *f, int l, const char *u) { void *p = (malloc)(size); printf ("Allocated = %s, %d, %s, %x\n", f, l, u, p); return p; }
(这样就可以评估LINE和朋友扩展宏的位置 – 否则它们总是相同的)。
将名称(malloc)
括在parantheses中可以防止宏malloc
被展开,因为它是一个类似函数的宏。
如果您在另一个看不到#Define的文件中实现了my_malloc(),该怎么办?
与new / delete不同,没有标准方法可以在标准C或C ++中覆盖malloc和free。
但是,大多数平台都会以某种方式允许您使用自己的标准库函数重新编译这些标准库函数,例如在链接时。
如果这不起作用,并且可移植性是必要的,首先声明函数,然后声明定义:
#include void *myMalloc(size_t size) { // log return malloc(size); } void myFree(void *ptr) { // log free(ptr); } #define malloc(size) myMalloc(size) #define free(ptr) myFree(ptr)
您应该使用LD_PRELOAD来覆盖这种函数(Library Interposer是我记不住的实际名称)..
这里解释
#define是一个宏替换。 对malloc(size)的调用将被my_malloc(size)替换。
如果您尝试#define
malloc
(保留标识符),那么程序的行为是未定义的,因此您应该尝试找到另一种方法来解决您的问题。 如果你真的需要这样做,那么这可能会奏效。
#include #define malloc(x) my_malloc(x) void *my_malloc(size_t x) { return (malloc)(x); }
像宏一样的函数只有当它们被发现为macro-name
后跟(
。malloc周围的额外括号意味着它不是这种forms所以它不被预处理器替换时)才会被展开。结果语法仍然是一个有效的函数调用所以真正的malloc仍将被调用。
#define malloc(X) my_malloc((X)) void* my_malloc(size_t size) { #define my_malloc(X) malloc((X)) void *p = malloc(size); printf ("Allocated = %s, %s, %s, %x\n",__FILE__, __LINE__, __FUNCTION__, p); return p; }
在函数my_malloc中,#define my_malloc(X)malloc((X))将起作用。 在此函数之外它没有任何效果。因此,将在my_malloc中调用C malloc函数