IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

"new" et les fonctions


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut "new" et les fonctions
    Bonsoir et bonne vacances pour tous/toutes ceux/celles qui sont en vacances,

    Je reviens avec une question que je me demande si je ne l'ai pas déjà posée.

    Alors voilà : la plupart du temps lorsqu'on déclare une fonction est se met quelque part dans la mémoire.
    Or voilà : est-il possible de crée une fonction et de dire "tu te mets dans la mémoire à l'endroit où je te dis".

    Il me semble que la pile a quelque chose à voir avec ça mais je ne suis pas sûr.

    Merci d'avance à vous. Bonne soirée.
    Cordialement, Gizmo.

  2. #2
    Membre éprouvé
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Points : 1 081
    Points
    1 081
    Par défaut
    quel intérêt ? que veux-tu faire ?
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Il n'y a pas moyen de forcer quoi que ce soit à se placer à une adresse mémoire précise, pour la simple et bonne raison que l'adresse est peut etre déjà utilisée par autre chose.

    Par contre, il est toujours possible de récupérer l'adresse mémoire de n'importe quoi se trouvant en mémoire, et ce, y compris pour l'adresse de début d'une fonction

    Il est donc en effet possible de "jouer" avec des pointeurs de fonctions, ce qui est une possibilité régulièrement utilisée pour implémenter un système de "callback".

    Le plus facile en C++ consiste en la définition d'un typedef proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef typederetour (* nomdutypedefSurPointeurDefonction) (/*<listdD'argument> */);
    puis de définir une variable de type nomdutypedefSurPointeurDefonction et d'y affecter, bien sur, une fonction dont la signature correspond à celle que l'on a déterminée.

    Ainsi, le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <iostream>
     
    /* déclare un type nommé "callbackType" comme étant un pointeur
     * de fonction ne prenant aucun argument et ne renvoyant rien
     */
    typedef void (*callbackType)();
    /* une première fonction ne prenant aucun argument et ne renvoyant rien
     */
    void hello()
    {
        std::cout<<"hello ";
    }
    /* une autre fonction ne prenant aucun argument et ne renvoyant rien
     */
    void world()
    {
        std::cout<<"world"<<std::endl;
    }
    void callIt(callbackType cb)
    {
       (*cb)();
    }
    int main()
    {
        /* nous aurions pu joindre les deux instructions suivantes, c'est
         * juste fait ici pour bien montrer les étapes successives
         */
        callbackType cb1 = NULL;
        /*affecte l'adresse de la fonction "hello" à notre pointeur de fonction
         */
        cb1 = hello;
     
        /*ce qui serait revenu au même que
         */
        callbackType cb2 = world;
        /* appelle la fonction
         */
       callIt(cb1);
       callIt(cb2);
        return 0;
    }
    nous affichera "hello world".

    Il existe cependant certaines subtilités dés que l'on souhaite travailler avec des pointeurs de fonctions membres de classes.

    Si cela t'intéresse, je m'étendrai volontiers sur le sujet
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre éprouvé
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Points : 1 081
    Points
    1 081
    Par défaut
    maintenant que j'y pense, tu ne voudrais pas faire du spoofing en remplaçant une fonction à une adresse par une autre que tu as créé par hasard ?
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Il n'y a pas moyen de forcer quoi que ce soit à se placer à une adresse mémoire précise.
    Si, avec le placement new.

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par oodini Voir le message
    Si, avec le placement new.
    Hummm... oui, mais non.

    Le placement new permet de faire en sorte que certaines données prennent place à une adresse mémoire déterminée par avance par le système, par contre, tu n'as aucun moyen de choisir toi même que telle donnée se trouvera à l'adresse 0xAA66DD77, par exemple, car tu n'as strictement aucun moyen de savoir si cette adresse est ne serait-ce qu'accessible pour ton programme ni si, étant accessible, elle n'est pas déjà occupée par autre chose.

    Je m'explique :

    Mettons que tu aies une structure "large" de 8 bytes.

    Tu peux réserver un espace mémoire de 200 bytes consécutifs et décider que la première donnée prendra les 0 à 7, la deuxième les bytes 8 à 15, la 20ieme les bytes 160 à 167 et ainsi de suite.

    Sous cet angle de vue, tu peux, effectivement, considérer que tu peux "forcer" tes données à prendre une adresse mémoire particulière.

    Par contre, l'adresse du byte 0, tu ne peux pas la choisir : c'est le système qui va la déterminer en fonction de tout un tas d'autres critères, à commencer par le fait de savoir si les 200 bytes sont alloués sur la pile ou sur le tas et, selon le cas, potentiellement sur base... de l'adresse à laquelle se trouve le point d'entrée de ton programme.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Invité
    Invité(e)
    Par défaut
    Dans le lien c'est quand même écrit
    Danger Il est de votre entière responsabilité de garantir que le pointeur que vous passez à l'opérateur "placement new" pointe sur une zone mémoire assez grande et correctement alignée pour l'objet que vous voulez y placer. Ni le compilateur ni le runtime de votre système ne vérifient que c'est effectivement le cas
    donc tout laisse penser qu'on peut choisir nous même l'adresse à laquelle faire lalloc mémoire.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par galerien69 Voir le message
    donc tout laisse penser qu'on peut choisir nous même l'adresse à laquelle faire lalloc mémoire.
    Non, cela veut dire que, si tu choisi l'adresse 0xAA66DD77 (par exemple avec un code qui pourrait ressembler à char * tab = 0xAA66DD77 ), le compilateur partira du principe que "tu sais ce que tu fais"...

    Mais je te déconseille quand même d'essayer

    On insiste en effet bien sur le fait que
    Il est de votre entière responsabilité de garantir que le pointeur que vous passez à l'opérateur "placement new" pointe sur une zone mémoire assez grande et correctement alignée
    Or, le seul moyen de le garantir, c'est soit de déclarer un tableau de taille suffisante (char tab[1600] pour coller à mon exemple précédent), soit de recourir à l'allocation dynamique (malloc ou new).

    Et ces deux solutions font que c'est le système qui a, en définitive, le dernier mot sur l'adresse mémoire à laquelle se trouvent les données
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @galerien69: Ca sous-entend surtout qu'il faut que tu n'utilises un placement new que sur une zone mémoire dont tu es certain d'avoir la propriété. Sinon ton OS va râler (probablement un SIGSEV sous un POSIX par exemple). D'autre part il faut aussi prendre garde à l'alignement (pour ca qu'il passe par un tableau de char dans la faq d'ailleurs), les fonctions d'allocation utilisées par le C++ doivent retourner des adresses avec un alignement spécifique (je connais pas les détails, l'idée est de pouvoir aligner un type quelconque dessus ensuite), or le placement new standard ne fait "rien" d'autre que d'utiliser l'adresse que tu lui donnes : tu lui donnes n'importe quoi, tu obtiens n'importe quoi.

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Hummm... oui, mais non.
    Tu disais que tu ne pouvais pas affecter une adresse précise, alors que c'est possible.

    Sans doute voulais-tu dire arbitraire.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par oodini Voir le message
    Tu disais que tu ne pouvais pas affecter une adresse précise, alors que c'est possible.

    Sans doute voulais-tu dire arbitraire.
    Oui, en effet... Au temps pour moi

    Bien vu
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Non je ne cherche pas à faire snoopy-fing ou à créer un virus quelconque.

    C'était une question comme ça comme j'en ai des fois.
    C'est formidable de pouvoir faire ça mais j'imagine que ça demande beaucoup... beaucoup de maîtrise !

    Bah je vais faire comme d'hab' c'est le mieux je pense.

    Par contre je ne sais pas ce qu'est le ploufing.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo