Проблема в переопределении malloc

От Эффективность по сравнению с намерением Andrew Koenig:

Первый, совсем не очевидно, что ++i более эффективно, чем i++, по крайней мере, где целочисленные переменные затронуты.

И:

, Таким образом, вопрос, который нужно задавать, не, какая из этих двух операций быстрее, это - какая из этих двух операций выражает более точно, что Вы пытаетесь выполнить. Я утверждаю, что, если Вы не используете значение выражения, никогда нет причины использовать i++ вместо ++i, потому что никогда нет причины скопировать значение переменной, увеличьте переменную, и затем выбросьте копию.

Так, если бы получающееся значение не используется, я использовал бы ++i. Но не потому что это более эффективно: потому что это правильно указывает мое намерение.

10
задан Aiden Bell 7 July 2009 в 20:05
поделиться

8 ответов

Проблема решена:

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__)
20
ответ дан 3 December 2019 в 13:27
поделиться

С Glibc существует malloc_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 .)

13
ответ дан 3 December 2019 в 13:27
поделиться

Чтобы исправить как проблему замены макросов, так и заставить 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) в скобки предотвращает выполнение макроса malloc расширяется, поскольку это макрос, подобный функции.

6
ответ дан 3 December 2019 в 13:27
поделиться

В отличие от 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)
3
ответ дан 3 December 2019 в 13:27
поделиться

Что, если бы вы реализовали my_malloc () в другом файле, который не видит #Define?

3
ответ дан 3 December 2019 в 13:27
поделиться

#define - это замена макроса. Вызов malloc (size) заменяется my_malloc (size).

1
ответ дан 3 December 2019 в 13:27
поделиться

Если вы попытаетесь использовать #define malloc (зарезервированный идентификатор), то поведение вашей программы не определено, поэтому вам следует попытаться найти другой способ решения вашей проблемы. проблема. Если вам действительно нужно это сделать, то это может сработать.

#include <stdlib.h>

#define malloc(x) my_malloc(x)

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

Такие функции, как макросы, раскрываются только в том случае, если они найдены как имя макроса , за которым следует (. Дополнительные скобки вокруг malloc означает, что он не такой формы, поэтому препроцессор не заменяет его. Результирующий синтаксис по-прежнему является допустимым вызовом функции, поэтому реальный malloc все равно будет вызываться.

0
ответ дан 3 December 2019 в 13:27
поделиться

Вы должны использовать LD_PRELOAD, чтобы перезаписать этот вид функции (Library Interposer - это настоящее имя, которое я не мог вспомнить) ..

Пояснение здесь

3
ответ дан 3 December 2019 в 13:27
поделиться