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 :

Surcharge de l'opérateur new


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut Surcharge de l'opérateur new
    Bonjour,

    J'ai besoin d'un peu d'aide sur une question de redéfinition des opérateurs d'allocation de mémoire. J'ai lu la partie traitant de ce point dans le tutorial de Loulou sur la réalisation d'un moteur 3D, mais certains points restent flous.

    Tout d'abord le contexte : le but est d'arriver à logger un message automatiquement dés qu'une allocation ne peut se faire correctement. Autrement dit on veut que le new se comporte exactement comme d'habitude, mis à part qu'avant de lancer une exception bad_alloc, il logge un message (dans un gestionnaire de log quelconque). L'application se débrouille ensuite avec cette exception.

    Comme je veux avoir un comportement le plus proche possible de celui par défaut, la question que je me pose est : comment l'opérateur new est-il implémenté en standard (j'utilise aCC sous HP-UX) ? Est-ce qu'il passe par malloc pour allouer les zones mémoire ? Autrement dit, si je surcharge new comme ceci :

    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
     
    #define new new(__FILE__, __LINE__)
     
    void* operator new (size_t size, const char* file, unsigned line)
    {
    	void* result = malloc(size);
     
    	if (!result)
    	{
    		// (ici on logge un message d'erreur par un quelconque gestionnaire de logs...)
    		throw bad_alloc();
    	}
     
    	return result;
    }
    ... est-ce que, en interne, le fonctionnement est réellement identique à ce qu'aurait fait le new standard, hormis le fait qu'on logge un message ? Ou est-ce que je m'en éloigne vraiment (fonctionnellement ou techniquement) ?

    Je demande ça car les problèmes techniques, aussi bien stabilité que perfs, sont extrêmement importants dans nos applications, et je ne veux pas que ces aspects techniques puisse être remis en cause d'une quelconque façon par cette surcharge.



    Ma deuxième question concerne les autres types d'erreurs lors de la construction. Là on a vu le problème de l'allocation en elle-même. Y aurait-il un moyen (sans toucher au code déjà fait) d'arriver à logger un message d'erreur dés qu'un constructeur (quelle que soit la classe) lance une exception ? A la suite de quoi elle serait relancée (throw afin de laisser l'application la traiter de façon plus appropriée. Je ne vois pas comment faire ça mais peut-être aurez vous une idée...


    Merci d'avance

  2. #2
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par www.informit.com/articles/article.asp?p=30642&seqNum=3
    In practice, storage allocated by an overloaded global operator new is often erroneously deallocated by the standard global operator delete. One way to avoid this error is to ensure that any storage allocated by an overloaded global operator new obtains that storage from the standard global operator new. This is what we've done with the first overloaded implementation above, and our first version works correctly with standard global operator delete:
    Très forte cette surcharge là, je l'avais carrément oublié ( )... Néanmoins, la citation ci-dessus confirme mon intuition : pas de mélanges malloc()/delete ou new/free() !!!
    Donc à priori new n'utilise pas malloc() mais un appel systeme de niveau inférieur...

    Y'a un exemple de new surchargé (je ne suis pas convaincu de la pertinence de l'exemple pour l'avoir testé, néanmoins, ça marche !!)

    Sinon, pourquoi ne pas tester le retour du new dans la macro ?? (Ce qui évite de bidouiller new : éventuellement rassurant!!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      #define TEST_NEW( x )  test_new_inline( x, __FILE__, __LINE__)
      // test_new_inline verifie que (x != (void*)0)
     
      Foo* bar = new Foo(arg1, arg2)
      TEST_NEW(bar);
    Je sais, du coup c'est pas automatique... Enfin il suffit de trouver toutes les occurences de "XXX = new" dans un code source et d'inserer une ligne !!!
    Un p'tit coup de sed, et hop!! PRESQU'automatique...
    Gaïa n'est pas une marchandise.

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut Re: Surcharge de l'opérateur new
    Citation Envoyé par :Bronsky:
    Tout d'abord le contexte : le but est d'arriver à logger un message automatiquement dés qu'une allocation ne peut se faire correctement. Autrement dit on veut que le new se comporte exactement comme d'habitude, mis à part qu'avant de lancer une exception bad_alloc, il logge un message (dans un gestionnaire de log quelconque). L'application se débrouille ensuite avec cette exception.
    Pour ça, pas besoin de surcharger new, il y a bien plus simple. Regarde du côté de set_new_handler.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut Re: Surcharge de l'opérateur new
    Citation Envoyé par SKZ81
    Sinon, pourquoi ne pas tester le retour du new dans la macro ?? (Ce qui évite de bidouiller new : éventuellement rassurant!!)
    Cette façon de faire m'est bien passé par la tête mais elle ne permet pas d'imbriquer un new dans autre chose, par exemple comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    uneFontion(new uneClasse());
    Or c'est justement pour ne pas me prendre la tête avec ce genre de cas que je veux trapper l'exception à la volée... après, libre à l'appli de catcher à son tour l'exception à cet endroit si elle le peut, mais le loggage systématique d'un message ne doit pas provoquer à lui seul la nécessité de scinder la ligne en deux.


    Citation Envoyé par SKZ81
    Citation Envoyé par www.informit.com/articles/article.asp?p=30642&seqNum=3
    In practice, storage allocated by an overloaded global operator new is often erroneously deallocated by the standard global operator delete. One way to avoid this error is to ensure that any storage allocated by an overloaded global operator new obtains that storage from the standard global operator new. This is what we've done with the first overloaded implementation above, and our first version works correctly with standard global operator delete:
    Très intéressante cette source, les infos sont très complètes ! Je ne connaissais pas le livre d'où elle est tirée, il a l'air top ! Il y a là l'info qui m'intéressais à savoir qu'on peut appeler le new standard à l'intérieur du new surchargé (bêtement j'avais pas pensé à la syntaxe ::operateur new() )... cette démarche est déjà nettement plus crédible que mon malloc !


    Citation Envoyé par JolyLoic
    Pour ça, pas besoin de surcharger new, il y a bien plus simple. Regarde du côté de set_new_handler.
    Ah oui tu as raison, pour cette simple application ça suffit amplement... Néanmoins il m'a également été demandé de rajouter les infos __LINE__ et __FILE__, et pour ça la surcharge avec 2 arguments de plus me semble indispensables...

    Merci pour toutes ces infos, j'essaie tout ça demain et je vous tiens au courant !

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Pour mettre du __LINE__ dedans, je ne connais pas de solution, puisque quelle que soit la façon dont tu compte remplacer new par une autre fonction, tu ne pourras avoir qu'un numéro de ligne dans ta fonction, alors que ce qui serait intéressant serait un numéro dans le code appelant.

    Ce genre de chose n'est hélàs possible qu'en remplaçant l'appel à new par une macro, et n'est donc pas transparent pour l'utilisateur.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par JolyLoic
    Pour mettre du __LINE__ dedans, je ne connais pas de solution, puisque quelle que soit la façon dont tu compte remplacer new par une autre fonction, tu ne pourras avoir qu'un numéro de ligne dans ta fonction, alors que ce qui serait intéressant serait un numéro dans le code appelant.

    Ce genre de chose n'est hélàs possible qu'en remplaçant l'appel à new par une macro, et n'est donc pas transparent pour l'utilisateur.
    Justement, si la macro s'appelle new, c'est transparent.
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par rolkA
    Citation Envoyé par JolyLoic
    Pour mettre du __LINE__ dedans, je ne connais pas de solution, puisque quelle que soit la façon dont tu compte remplacer new par une autre fonction, tu ne pourras avoir qu'un numéro de ligne dans ta fonction, alors que ce qui serait intéressant serait un numéro dans le code appelant.

    Ce genre de chose n'est hélàs possible qu'en remplaçant l'appel à new par une macro, et n'est donc pas transparent pour l'utilisateur.
    Justement, si la macro s'appelle new, c'est transparent.
    Ouaip, comme dans le tutorial de Loulou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define new new(__FILE__, __LINE__)
    Là c'est totalement transparent.

    J'essaie tout ça aujourd'hui...

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    J'ai une petite question intermédiaire... Dans l'article référencé plus haut, la zone mémoire est allouée comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *p = static_cast<char *>(::operator new( n ));
    J'imagine que c'est parce que son exemple consiste à initialiser la zone selon un pattern que l'auteur passe par un char, et que pour une application plus générale il suffit de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void* p = ::operator new(n);
    Me trompe-je ?
    (je ne suis pas très sur de moi sur ces trucs bas niveau désolé)

  9. #9
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Moi non plus en fait (je suis pas sûr de toi... )

    A mon avis oui, ça doit le faire... J'ai pas bien fait le tri dans tout ça, mais à mon avis tu ne te trompeux-je pas... Je pense que je serais parti dans cette voie.

    Quelqu'un a une objection ?
    Gaïa n'est pas une marchandise.

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par :Bronsky:
    Ouaip, comme dans le tutorial de Loulou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define new new(__FILE__, __LINE__)
    Là c'est totalement transparent.
    Tout d'abord, ce code n'est pas légal dans presque tous les cas...
    Citation Envoyé par 17.4.3.1.1/2
    A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.
    Et en plus, même s'il l'était, je doute qu'il fasse ce qu'il faut avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *toto=new char[100];
    MaClasse *m = new (toto) MaClasse;
    class A
    {
      void operator new (size_t size);
    }
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Voilà j'ai essayé aujourd'hui cette implémentation, elle fonctionne parfaitement. Il nous reste à la déployer sur l'ensemble des sources pour faire un test grandeur nature...


    Citation Envoyé par JolyLoic
    Tout d'abord, ce code n'est pas légal dans presque tous les cas...
    Citation Envoyé par 17.4.3.1.1/2
    A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.
    Oui je me doute bien que cette méthode n'est pas très propre, mais quelle autre solution a-t-on ? Nous avons réellement besoin d'obtenir ces infos, et il nous les faut en production, donc pas question de compiler en mode debug pour les obtenir...

    Citation Envoyé par JolyLoic
    Et en plus, même s'il l'était, je doute qu'il fasse ce qu'il faut avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *toto=new char[100];
    MaClasse *m = new (toto) MaClasse;
    class A
    {
      void operator new (size_t size);
    }
    Effectivement, voilà 2 cas pour lesquels la présence de la macro sera fatale à la compil. Heureusement nous n'utilisons de "placement new" et ne redéfinissons jamais new, mais il est vrai que ça pourrait toujours arriver...

    Bref je vois bien que cette méthode est un peu triviale, mais je ne vois pas d'autre solution...

  12. #12
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Eventuellement :
    Declarer la macro _new (ou n'importe quoi d'autre), on deviens ainsi conforme avec la loi...
    Ensuite, créer un script utilisant sed, gawk ou que sais-je encore qui remplace les occurences de
    "=", nombre d'ESP qqonque, "new", ESPs, PAS "("
    On evite ainsi de modifier les operator new, les ::new, les new(toto). A la place de PAS "("', on peux même attendre [_A-Za-z], car tout identificateur commence par un caractère dans cet ensemble.

    On applique le script sur tout le source (h/cpp), ce qui produit une version altéré... Que l'on compile et ho, bonheur !!!

    Tout celà sans changer les habitudes des codeurs (dans le source) ni leur sacro-saint
    qui se chargera d'appeller le script !! (et éventuellement efface les sources altérés)
    Enfin tout ça c'est une idée, qui demande de se pencher sur la grammaire du C++ pour prouver (disons checker) que tous les cas possibles sont géré. Un peu fastidieux de s'y mettre je pense mais pas énorme. En plus ici y'en a qui l'on trifouillé, j'ai vu des post à ce sujet y'a pas longtemps.

    [edit]
    Mea culpea, je crois encore être dans dev linux...
    [/edit]
    Gaïa n'est pas une marchandise.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Là on touche carrément à la procédure de build qui nous sert à produire les release et les patchs, c'est une partie du projet qui ne me concerne pas et que je ne peux pas me permettre d'influer pour si peu.

    En plus, au moment du build les sources sont en read-only car elles descendent d'un outils de gestion de config (PVCS) et je ne me vois pas demander au responsable des builds de se logger en root et de faire un chmod -R 777 avant de lancer le bousin

    S'il n'y avait que mes propres compils dans le cadre de mes dév ça irait, mais il faut penser à toutes les étapes jusqu'à la release finale... là ça va trop loin. Une fois les sources remontées dans PVCS par les développeurs, personnes ne doit y toucher.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Me revoilou, je reviens vers vous avec un peu de retard (on a eu d'autre priorité entre temps, désolé).

    Bon j'avais réussi à tester mon new surchargé en local sous windows et ça marchait très bien. Là je suis en train de l'intégrer réellement dans le projet, sous Unix HP-UX (compilo aCC). Or il y a un warning qui ne me plait pas beaucoup, au moment d'appeler le new surchargé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Placement operator delete invocation is not yet implemented.
    En gros il me dit que je n'ai pas défini d'opérateur delete correspondant à mon new surchargé. Pourtant je pense l'avoir fait, voici mon .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void* operator new (size_t size, const char* file, unsigned line);
    void* operator new[] (size_t size, const char* file, unsigned line);
    void operator delete (void* p, const char*, unsigned);
    void operator delete[] (void* p, const char*, unsigned);
    Je sais bien que de cette façon c'est le delete de base et non le delete surchargé qui sera appelé, et qu'il faut une bidouille supplémentaire pour qu'il le soit. Mais en l'occurence, le delete de base convient parfaitement car le new surchargé fait finalement appel au new de base. Je n'ai défini ce delete surchargé que pour faire plaisir au compilo, alors ça m'embête un peu qu'il fasse comme s'il ne l'avait pas vu

  15. #15
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je ne suis pas sûr que ce warning signifie qu'il manque une surcharge pour l'opérateur delete.

    Par contre ce n'est pas pour faire plaisir au compilo que tu as codé ces surcharges, mais bien pour éviter des fuites mémoires . En effet les versions de delete avec des paramètres supplémentaires sont appelées par le compilo dans certains cas (rares), à savoir lorsque le new ou new [] correspondant ne peut pas allouer la mémoire ou lorsque le constructeur de l'objet construit lève une exception. La norme spécifie alors que c'est la surcharge de delete / delete [] correspondante qui sera appelée, avec comme valeurs pour ses paramètres celles qu'avait reçues new / new [].

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Ah OK d'acc... Je ne connaissais pas ce comportement automatique. Bon pour l'instant je teste avec mes warnings (j'ai qques problèmes d'intégration, c'est une vraie usine à gaz) en espérant que ça marchera, mais à plus long terme il faut que j'arrive à comprendre ce qu'il signifie et comment l'éliminer

  17. #17
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En fait je crois qu'il s'agit simplement d'une fonctionnalité manquante du compilo. Essaye de créer un objet qui lève une exception (dans son constructeur) avec ton new surchargé, et regarde si le compilo appelle bien le delete correspondant.

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : Japon

    Informations forums :
    Inscription : Mai 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Permettez ma réponse 5 ans plus tard, mais j'aimerais confirmer ce qui a été dit plus haut concernant le placement new et les exceptions, pour ceux qui survolent ce sujet et qui seraient intéressés :

    Je viens de trouver ça :
    Citation Envoyé par http://www.linux-kheops.com/doc/cours/cours_cpp/htm/x3134.htm
    Il est impossible de passer des paramètres à l'opérateur delete dans une expression delete. Cela est dû au fait qu'en général, on ne connaît pas le contexte de la destruction d'un objet (alors qu'à l'allocation, on connaît le contexte de création de l'objet). Normalement, il ne peut donc y avoir qu'un seul opérateur delete. Cependant, il existe un cas où l'on connaît le contexte de l'appel de l'opérateur delete : c'est le cas où le constructeur de la classe lance une exception (voir le Chapitre 9 pour plus de détails à ce sujet). Dans ce cas, la mémoire allouée par l'opérateur new doit être restituée et l'opérateur delete est automatiquement appelé, puisque l'objet n'a pas pu être construit. Afin d'obtenir un comportement symétrique, il est permis de donner des paramètres additionnels à l'opérateur delete. Lorsqu'une exception est lancée dans le constructeur de l'objet alloué, l'opérateur delete appelé est l'opérateur dont la liste des paramètres correspond à celle de l'opérateur new qui a été utilisé pour créer l'objet. Les paramètres passés à l'opérateur delete prennent alors exactement les mêmes valeurs que celles qui ont été données aux paramètres de l'opérateur new lors de l'allocation de la mémoire de l'objet. Ainsi, si l'opérateur new a été utilisé sans placement, l'opérateur delete sans placement sera appelé. En revanche, si l'opérateur new a été appelé avec des paramètres, l'opérateur delete qui a les mêmes paramètres sera appelé. Si aucun opérateur delete ne correspond, aucun opérateur delete n'est appelé (si l'opérateur new n'a pas alloué de mémoire, cela n'est pas grave, en revanche, si de la mémoire a été allouée, elle ne sera pas restituée). Il est donc important de définir un opérateur delete avec placement pour chaque opérateur new avec placement défini.
    Conclusion : pour chaque placement new, il est très fortement conseillé d'écrire un placement delete correspondant, afin d'éviter des pertes mémoire en cas d'exception levée à la construction.

    J'espère que ça aidera ^^

Discussions similaires

  1. Surcharge de l'opérateur new
    Par asaleth dans le forum C++
    Réponses: 9
    Dernier message: 30/03/2015, 21h18
  2. Compiler la surcharge de l'opérateur new
    Par mutagling dans le forum Langage
    Réponses: 1
    Dernier message: 24/06/2010, 07h24
  3. surcharger l'opérateur NEW
    Par spiner900 dans le forum Langage
    Réponses: 2
    Dernier message: 22/04/2010, 16h38
  4. Surcharge de l'opérateur new
    Par asoka13 dans le forum C++
    Réponses: 4
    Dernier message: 09/05/2008, 12h44
  5. namespace et opérateur new
    Par Sylvain Rousseau dans le forum C++
    Réponses: 3
    Dernier message: 06/01/2005, 23h24

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