10
votes

Problème dans le remplacement du malloc

J'essaie de remplacer MALLOC en faisant cela.

#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;
}

c c++

2 commentaires

Peut-être devrait changer de titre en quelque chose de plus spécifique. Le problème n'a vraiment rien à voir avec Malloc ou remplacer, mais plutôt avec des macros de préprocesseur et d'accéder au nom d'origine.


Cela ne fonctionnera pas comme vous le souhaitez: __ fichier __ , __ ligne __ et __ fonction __ (C99 Syntax serait __ func __ ) va toujours étendre à la même valeur en fonction de leur placement dans le fichier contenant my_malloc () ; Vous devez les mettre dans votre définition macro et les transmettre à my_malloc () comme arguments!


9 Réponses :


3
votes

Et si vous implémentez my_malloc () dans un fichier différent qui ne voit pas le #define?


1 commentaires

Je pense que c'est une solution plus flexible. La plupart des gens recherchent #defines au sommet d'un fichier aussi, un point de confusion.



1
votes

#define est un remplacement macro. L'appel à malloc (taille) est remplacé par MY_MALLALC (taille).


0 commentaires

20
votes

problème résolu: xxx


2 commentaires

+1 pour faire apparaître ma solution lorsque j'ai appuyé sur de nouvelles réponses. :) L'explication est que A #define ne prend effet que pour le code qui apparaît après que cela soit invoqué.


Le problème avec cela (et pourquoi il peut pas être résolu), est-ce que cela ne fonctionne que si vous ne tenez pas compte des bibliothèques existantes déjà compilées et appelant MALLOC (que votre propre code peut être responsable de la gestion ). Dans ce cas, vous pouvez faire quelque chose comme ceci: Stackoverflow.com/Questtions/6083337/...



4
votes

Contrairement à la nouvelle / Supprimer, il n'y a pas de moyen standard de remplacer malloc et gratuitement dans la norme C ou C ++.

Cependant, la plupart des plates-formes vous permettront de recouvrir ces normes Fonctions de la bibliothèque avec votre propre, par exemple à l'heure de liaison. P>

Si cela ne fonctionne pas et que la portabilité est nécessaire, déclarez d'abord les fonctions, puis déclarez les définies: P>

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


0 commentaires

3
votes

Vous devez utiliser ld_preload pour écraser ce type de fonction (interposeur de la bibliothèque est le nom réel que je ne pouvais me souvenir) ..

explication ici


0 commentaires

1
votes

Si vous essayez de #define code> MALLOC code> (un identifiant réservé), le comportement de votre programme est indéfini afin que vous puissiez essayer de trouver un autre moyen de résoudre votre problème. Si vous avez vraiment besoin de le faire, cela peut fonctionner.

#include <stdlib.h>

#define malloc(x) my_malloc(x)

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


7 commentaires

Qu'est-ce qui te fait penser que Malloc est un mot réservé? Ce n'est pas le cas, et même si c'était le préprocesseur s'en ficherait!


Reserver 'Identifiant', non réservé. 7.1.3 / 1 'Tous les identificateurs avec une liaison externe dans l'un des sous-clauses suivants ...'


Merci, mais encore une fois: qu'est-ce que le préprocesseur se soucie? MALLOC est réservé dans le contexte de liaison externe et pas Définition macro


Le préprocesseur fait partie de la mise en œuvre. La mise en œuvre est autorisée à compter sur le programmeur ne faisant pas de choses qui entraînent un comportement indéfini. Peut-être une macro de bibliothèque standard utilise MALLOC de manière à ne pas avoir été # définir par le programmeur. 7.1.3 / 2 Cleary stipule que si un programme définit un identifiant réservé sous forme de nom de macro, le comportement n'est pas défini. Certaines implémentations peuvent être autorisées, mais c'est une extension de langue non portable.


@CHARDLES: 7.1.3 §2 semble incompatible avec 7.1.4, en particulier la note de bas de page 163), qui mentionne explicitement l'utilisation de #undef pour révéler le prototype d'une fonction de bibliothèque qui pourrait être ombragé par la définition d'une macro comme une fonction; donc si vous utilisez #undef malloc pour vous assurer que vous avez affaire à un prototype réel (ou n'incluez tout simplement pas du tout), il devrait être raisonnablement sûr d'utiliser un #define ; Je vais devoir méditer encore plus sur le libellé exact de la norme pour voir où provient cette contradiction perçue; Seulement considéant 7.1.3 §2, je devrais être d'accord avec vous


C'est probablement une bonne règle que, si vous devez méditer sur la norme pour déterminer si quelque chose est autorisé, c'est probablement une mauvaise idée de le faire quand même.


7.1.3 comprend une clause disant "sauf comme autorisé par 7.1.4". 7.1.4 Donne la licence de programme pour faire certaines choses telles que #undef un masquage macro ou avancement déclarer une fonction de bibliothèque standard. Il ne donne pas la licence de programme pour déclarer une macro avec le même nom que la fonction de bibliothèque et 7.1.3 interdit expressément cela. Je ne vois pas l'incohérence. Vous êtes la numérotation de la note de bas de page est incompatible avec ma copie de la norme (ISO / CEI 9899: 1999), nous pouvons donc regarder différentes versions.



13
votes

avec glibc , il existe MALLOC_HOOK (3) CODE> comme le approprié em> moyen d'interposer globalement votre propre Malloc code> fonction.

$ 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!


0 commentaires

7
votes

Pour réparer à la fois le problème de remplacement de la macro et faire LIGNE ETC, car vous espérez qu'ils seront: xxx

(de cette façon ligne et les amis seront évalués lorsque la macro est élargie - sinon, ils seraient toujours les mêmes).

enfermer le nom (MALLOC) dans les paroseses empêche la macro MALLOC d'être étendu, car il s'agit d'une macro de forme de fonction.


0 commentaires

-2
votes
#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; 
} 
Here inside the function my_malloc, #define my_malloc(X) malloc((X)) will work. Outside this function it has no effect.Therefor, C malloc function will be invoked inside my_malloc 

0 commentaires