Come sostituire correttamente gli operatori globali di nuova ed eliminazione

Prima di tutto, c‘erano almeno 4-5 argomenti con un argomento simile su SO. Leggo ciascuno di loro e non credo che mi aiutino davvero con questo specifico problema. Se qualcun altro trova una domanda duplicata, mi scuso. Ho fatto la mia parte di ricerche prima di pubblicare questo, poiché sembra una domanda molto comune.

Sto usando Visual Studio .NET 2003 su Windows 7.

Ho il mio sovraccarico di nuovo / cancella quel punto alle mie chiamate personalizzate a malloc () e free () per la diagnostica. I miei nuovi overload / delete sono in un file di intestazione che ho incluso in alcuni file.

Il problema è che la base di codice è praticamente spaghetti e non esiste un modo semplice per assicurarsi che questi sovraccarichi vengano usati da tutto. Sono incluse le librerie di terze parti che sono black-box. Usiamo anche STL ovunque.

Nei miei test ho riscontrato che STL sta ancora mixando le chiamate al mio nuovo / delete e alle nuove chiamate MSVC standard / di eliminazione.

Non sembra realistico includere il mio file di intestazione in migliaia di altri file, il che richiederebbe troppo tempo. Qualcuno può offrire alcuni suggerimenti su come correttamente ed efficacemente sovraccaricare nuovo / eliminare globalmente, quindi tutto utilizza il mio gestore di memoria personalizzato?

Non è così che funziona. Sostituisci i due operatori e questo viene fatto al momento del collegamento . Tutto ciò che devi fare è scrivere una TU singola che definisca questi operatori e collegali al mix. Nessun altro ha mai bisogno di sapere su questo:

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

In linea di principio, non è necessario che i file di intestazione dichiarino queste funzioni ( operator new , operator delete ), poiché le dichiarazioni di queste due funzioni sono già codificate nel linguaggio, se lo si desidera. Tuttavia, i nomi std , std::bad_alloc e std::size_t non sono predeterminati, quindi probabilmente vorrai includere o qualche altra intestazione per fornire quei nomi.

In C ++ 11 e oltre, puoi in alternativa usare decltype(sizeof(0)) per ottenere la dimensione del primo parametro in un modo che non richiede alcun tipo di libreria. C ++ 11 ha anche un modello di eccezione più semplice senza specifiche di eccezione dinamiche (che sono state finalmente rimosse dal linguaggio interamente in C ++ 17).

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

Aggiungi anche queste righe:

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