重写malloc时出现问题

时间:2009-07-07 20:02:25

标签: c++ c

我试图通过这样做来覆盖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函数而不是宏实现。你能告诉我怎么做吗?

感谢。

9 个答案:

答案 0 :(得分:20)

问题解决了:

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__)

答案 1 :(得分:13)

使用Glibcmalloc_hook(3)作为正确的方式全局介入您自己的malloc函数。

#include <stdio.h>
#include <malloc.h>

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'
(the code above)
EOF
$ cat >main.c <<'EOF'
#include <stdio.h>
#include <stdlib.h>
int main() {
    char *buf = malloc(50);
    sprintf(buf, "Hello, world!");
    puts(buf);
    free(buf);
    return 0;
}
EOF
$ cc mem.c main.c
$ ./a.out
0x40077e: malloc(50) = 0x22f7010
Hello, world!

(我们可以使用__attribute__((constructor)),但这个技巧不是必需的:Glibc轻松提供__malloc_initialize_hook作为在main之前加载运行代码的另一种方法。)

答案 2 :(得分:5)

要修复宏替换问题,并使 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,因为它是一个类似函数的宏。

答案 3 :(得分:3)

如果您在另一个看不到#Define的文件中实现了my_malloc(),该怎么办?

答案 4 :(得分:3)

与new / delete不同,没有标准方法可以覆盖malloc和free 在标准C或C ++中。

但是,大多数平台都会以某种方式让您重新使用这些标准 库函数与您自己的函数,例如在链接时。

如果这不起作用,并且可移植性是必要的,首先声明函数,然后声明定义:

#include <stdlib.h>

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)

答案 5 :(得分:3)

您应该使用LD_PRELOAD来覆盖这种功能(Library Interposer是我记不住的实际名称)..

解释here

答案 6 :(得分:1)

#define是一个宏替换。对malloc(size)的调用将被my_malloc(size)替换。

答案 7 :(得分:0)

如果您尝试#define malloc(保留标识符),那么您的程序行为是未定义的,因此您应该尝试找到另一种方法来解决您的问题。如果你真的需要这样做,那么这可能会有效。

#include <stdlib.h>

#define malloc(x) my_malloc(x)

void *my_malloc(size_t x)
{
        return (malloc)(x);
}

只有在macro-name后跟(时才会展开宏等功能。 malloc周围的额外括号表示它不是这种形式,因此它不会被预处理器替换。结果语法仍然是一个有效的函数调用,因此仍将调用真正的malloc。

答案 8 :(得分:-1)

#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函数