web-dev-qa-db-fra.com

Comment remplacer correctement les nouveaux opérateurs globaux et supprimer

Tout d'abord, il y avait au moins 4-5 sujets avec un sujet similaire sur SO. J'ai lu chacun d'eux et je ne pense pas qu'ils m'aident vraiment avec ce problème spécifique. Si quelqu'un d'autre trouve une question en double, je m'en excuse. J'ai fait ma part de recherche avant de poster ceci, car cela semble être une question très courante.

J'utilise Visual Studio .NET 2003 sur Windows 7.

J'ai mes propres surcharges de nouveaux/supprimer qui pointent vers mes propres appels personnalisés à malloc () et free () pour les diagnostics. Mes nouvelles surcharges/suppressions sont dans un fichier d'en-tête que j'ai inclus dans quelques fichiers.

Le problème est que la base de code est à peu près des spaghettis et il n'y a pas de moyen facile de s'assurer que ces surcharges sont utilisées par tout. Il existe des inclus dans les bibliothèques tierces qui sont en boîte noire. Nous utilisons également STL partout.

Dans mes tests, j'ai découvert que STL mélange toujours les appels à mes propres appels new/delete et MSVC standard new/delete.

Il ne semble pas réaliste d'inclure mon fichier d'en-tête dans des milliers d'autres fichiers, cela prendrait beaucoup trop de temps. Quelqu'un peut-il offrir des conseils sur la façon de surcharger correctement et efficacement les nouveaux/supprimer globalement afin que tout utilise mon gestionnaire de mémoire personnalisé?

54
void.pointer

Ce n'est pas comme ça que ça fonctionne. Vous remplacez les deux opérateurs, et cela se fait au moment du lien . Tout ce que vous avez à faire est d'écrire un seul TU qui définit ces opérateurs et le relie au mix. Personne d'autre jamais besoin de savoir à ce sujet:

// optional_ops.cpp

void * operator new(std::size_t n) throw(std::bad_alloc)
{
  //...
}
void operator delete(void * p) throw()
{
  //...
}

En principe, aucun fichier d'en-tête n'est nécessaire pour déclarer ces fonctions (operator new, operator delete), Car les déclarations de ces deux fonctions sont déjà codées en dur dans la langue, si vous voulez. Cependant, les noms std, std::bad_alloc Et std::size_t Ne sont pas pas prédéclarés, vous devrez donc probablement souhaitez inclure <new> ou un autre en-tête pour fournir ces noms.

Dans C++ 11 et au-delà, vous pouvez également utiliser decltype(sizeof(0)) pour obtenir la taille du premier paramètre d'une manière qui ne nécessite aucun type de bibliothèque. C++ 11 possède également un modèle d'exception plus simple sans spécifications d'exceptions dynamiques (qui ont finalement été entièrement supprimées du langage en C++ 17).

void * operator new(decltype(sizeof(0)) n) noexcept(false)
{
  //...
}
75
Kerrek SB

Ajoutez également ces lignes:

void *operator new[](std::size_t s) throw(std::bad_alloc)
{
    // TODO: implement
    return NULL;
}
void operator delete[](void *p) throw()
{
    // TODO: implement
}
34
Extrunder