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

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 980
    Points : 11 089
    Points
    11 089
    Billets dans le blog
    1

    Par défaut [C++17] Remplacement global de new et delete

    Bonjour,

    Je fais (toujours) de l'embarqué (mais maintenant je fais du C++17) et j'aimerais traquer les allocations dynamiques de mémoire. Mon idée a donc été de remplacer les opérateurs new et delete globaux. Pour cela, j'ai lu les deux sections Global replacements des deux pages suivantes :
    http://en.cppreference.com/w/cpp/mem...w/operator_new
    http://en.cppreference.com/w/cpp/mem...perator_delete

    J'en suis arrivé à la conclusion que je devais remplacer la version (1) de new et les versions (1) et (3) de delete. J'ai obtenu le code suivant, placé dans un fichier dédié :
    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
    #include <cstdio>
    #include <cstdlib>
     
    std::size_t allocated = 0;
    unsigned int untracked_deletes = 0;
     
    void* operator new(std::size_t size) {
    	std::printf("global op new called, size = %zu\n", size);
     
    	allocated += size;
    	return std::malloc(size);
    }
     
    void operator delete(void* ptr) noexcept
    {
    	std::puts("Delete no size");
    	++untracked_deletes;
    	std::free(ptr);
    }
     
    void operator delete(void* ptr, std::size_t size) {
    	std::printf("global op delete called, size = %zu\n", size);
     
    	allocated -= size;
    	std::free(ptr);
    }
    Pour vérifier que ça fonctionne correctement, j'ai ensuite écrite un deuxième fichier cpp avec :
    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
    #include <cstdio>
     
    extern std::size_t allocated;
    extern unsigned int untracked_deletes;
     
    class Foo {
    	int array[32];
    };
     
    int main() {
    	auto pi = new int;
    	delete pi;
     
    	auto pa = new int[10];
    	delete[] pa;
     
    	auto pf = new Foo;
    	delete pf;
     
     
    	std::printf("Allocated %zu ; untracked %u", allocated, untracked_deletes);
    }
    La sortie en console donne avec mingw64 / gcc7:
    global op new called, size = 4
    Delete no size
    global op new called, size = 128
    Delete no size
    Allocated 132 ; untracked 2
    Je constate que new[] ne rappelle pas ma version de new. J'ai l'impression que cela correspondrait à la version (2) qui est pourtant décrite comme ceci :
    2) Called by the array form of new[]-expressions to allocate all storage required for an array (including possible new-expression overhead). The standard library implementation calls version (1)
    Qu'est ce que j'ai raté ?

    Merci d'avance !

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 980
    Points : 11 089
    Points
    11 089
    Billets dans le blog
    1

    Par défaut

    En fait j'ai dit une bêtise : je ne redéfinis pas la version 3 de delete.

    J'avais d'abord mis uniquement la version 1 mais le warning -Wsized-deallocation de GCC m'a dit que je devais ajouter une variante (celle que vous voyez dans mon code, qui est donc la version 5 si je ne dis pas de bêtise).

  3. #3
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 525
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 525
    Points : 24 092
    Points
    24 092

    Par défaut

    J'en pense que tu devrais réimplémenter new[] et delete[] également et ne pas compter sur une ligne de doc qui décrète qu'une éventuelle implémentation utilise new : on n'a aucune idée de ce qu'ils entendent par là, et ça peut très bien ne pas être un appel à new explicitement comme tu l'entends mais n'utiliser que les mêmes mécanismes, ou des similaires, ou ...
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2004
    Messages
    5 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 444
    Points : 15 894
    Points
    15 894

    Par défaut

    J'ai testé ton code sous http://coliru.stacked-crooked.com/

    Avec gcc (7.2) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    global op new called, size = 4
    global op delete called, size = 4
    global op new called, size = 40
    Delete no size
    global op new called, size = 128
    global op delete called, size = 128
    Allocated 40 ; untracked 1
    Avec clang (3.8):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    global op new called, size = 4
    Delete no size
    global op new called, size = 128
    Delete no size
    Allocated 132 ; untracked 2
    Pour moi, le comportement que tu as ressemble plus à un bug qu'à autre chose.

    Sinon, la question que je me pose : Tu n'as pas à ta disposition des outils un peu plus évolués que ça pour effectuer ce genre de tests ? Si le problème est l'embarqué, tu ne peux pas dans un premier temps tester ton programme dans un environnement moins hostile, avec plus d'outils disponibles ?

    @Bousk : C'est plus qu'une ligne de doc, c'est requis dans la norme. Mais effectivement, d'un point de vue pragmatique, ta suggestion est probablement bonne
    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.

Discussions similaires

  1. Redéfinition opérateurs new et delete globaux
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 30/07/2007, 12h34
  2. Surdéfinition de new et delete
    Par couet dans le forum C++
    Réponses: 3
    Dernier message: 09/02/2007, 16h19
  3. surdefinition operateur new et delete
    Par johjoh dans le forum C++
    Réponses: 23
    Dernier message: 08/12/2006, 11h10
  4. intrigue sur la surcharge du new et delete
    Par swirtel dans le forum C++
    Réponses: 12
    Dernier message: 07/09/2006, 16h23
  5. Segmentation fault sur new[] et delete[]
    Par Don ViP dans le forum C++
    Réponses: 4
    Dernier message: 30/04/2006, 01h29

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