web-dev-qa-db-fra.com

surcharge nouveau / supprimer

Je fais un petit Finder de fuite de mémoire dans mon programme, mais ma façon de surcharger new et delete (et aussi new [] et delete []) ne semble rien faire.

void* operator new (unsigned int size, const char* filename, int line)
{
    void* ptr = new void[size];
    memleakfinder.AddTrack(ptr,size,filename,line);
    return ptr;
}

La façon dont j'ai surchargé new est indiquée dans l'extrait de code ci-dessus. Je suppose que c'est quelque chose avec l'opérateur retournant void * mais je ne sais pas quoi faire à ce sujet.

24
Brammie
void* ptr = new void[size];

Je ne peux pas faire ça. Répare le.

N'essayez jamais de surcharger new/delete globalement. Soit les avoir dans une classe de base et dériver tous vos objets de cette classe ou utiliser un espace de noms ou un paramètre d'allocation de modèle. Pourquoi, vous pouvez demander. Parce que dans le cas où votre programme est plus qu'un seul fichier et en utilisant STL ou d'autres bibliothèques, vous allez bousiller.

Voici une version distillée de l'opérateur new de VS2005 new.cpp:

void * operator new(size_t size) _THROW1(_STD bad_alloc)
{       // try to allocate size bytes
   void *p;
   while ((p = malloc(size)) == 0)
    if (_callnewh(size) == 0)
     {       // report no memory
        static const std::bad_alloc nomem;
        _RAISE(nomem);
     }

     return (p);
}
6
dirkgently

RÉ:

N'essayez jamais de surcharger de nouveaux/supprimer globalement

Pourquoi chaque fois que quelqu'un essaie d'utiliser une fonctionnalité moins courante de C++, quelqu'un agit comme si cela ne devait jamais être fait?

C'est fait tout le temps, c'est assez courant, et je n'ai pas travaillé pour une entreprise qui ne l'a pas fait.

La surcharge et les suppressions globales sont extrêmement utiles pour le suivi de la mémoire, des bogues de mémoire, des dépassements de mémoire tampon, etc.

Personne sensé ne va passer par un programme avec plusieurs millions de lignes de code et ajouter un nouveau membre et supprimer un membre à chaque classe. C'est juste stupide.

139
Dan

Vous pouvez peut-être faire ce que vous voulez avec un peu de magie du préprocesseur:

#include <iostream>

using namespace std;

void* operator new (size_t size, const char* filename, int line) {
    void* ptr = new char[size];
    cout << "size = " << size << " filename = " << filename << " line = " << line << endl;
    return ptr;
}

#define new new(__FILE__, __LINE__)

int main() {
    int* x = new int;
}
51
kyku

Je pense que le problème ici est que le profil de paramètre de votre nouveau ne correspond pas à celui de l'opérateur standard nouveau, de sorte que celui-ci ne se cache pas (et est donc toujours utilisé).

Vos profils de paramètres pour les nouveaux et les supprimer doivent ressembler à ceci:

void* operator new(size_t);
void operator delete(void*, size_t);
12
T.E.D.

Invoquez-vous correctement l'opérateur surchargé, c'est-à-dire en lui passant les paramètres supplémentaires?

4
zvrba

Le problème est lié aux deux arguments que vous avez ajoutés au nouvel opérateur surchargé. Essayez de rendre le nom de fichier et la ligne globaux d'une manière ou d'une autre (ou les variables membres si vous surchargez new et delete pour une seule classe). Cela devrait mieux fonctionner.

4
Benoît