2014-08-31 21 views
6

Sto cercando di ottenere informazioni sui pool di memoria in C++ per una migliore velocità e capacità di debug. Ho seguito l'approccio trovato qui: http://oroboro.com/overloading-operator-new/. Così ho sovraccaricato new, new[], delete, e delete[] come questo:Eliminazione sovraccarico globale [] non richiamato nelle librerie di terze parti

inline void* operator new  (size_t size) { return myAlloc(size); } 
inline void* operator new[] (size_t size) { return myAlloc(size); } 
inline void operator delete (void* ptr ) { myFree(ptr); } 
inline void operator delete[](void* ptr ) { myFree(ptr); } 

mi piace che le librerie di terze parti sono diretti a questa versione di new, ma mi sono imbattuto in un problema. Sto creando un'applicazione DirectX che utilizza DXUT. Compilare DXUT separatamente dal mio progetto. Alla fine si chiama:

std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData(new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]); 

Una volta che questo indicatore unico va fuori del campo di applicazione, si blocca su una chiamata a delete[] _Ptr, che non è andato attraverso la mia operatore di overload. Ho provato a eseguire il debug dell'implementazione del pool di memoria aggiungendo uno int* dummy = new int[10]; delete[] dummy; nel mio main. Costruire il progetto ha dato un errore, ma la costruzione pulita ha funzionato bene. Con mia sorpresa, tutto ha funzionato, compresa la linea DXUT che si è bloccata!

Domanda 1: cosa è successo esattamente quando ho aggiunto la riga di debug che ha risolto il problema? Immagino che per qualche ragione il mio operatore delete [] non fosse noto fino a quando non l'ho chiamato nel mio codice applicazione? Questo è garantito per risolvere il problema o è solo una sciocca fortuna?

Domanda 2: ho notato che il new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] non ha chiamato i miei operator new[] direttamente, ma alla fine chiamato il mio operator new (senza parentesi). Chiama ancora l'operatore delete[] sul puntatore. Questo pone un problema? Devo aggiungere il sovraccarico appropriato in modo tale che venga chiamato il mio operator new[] o questo comportamento sia corretto?

Per riferimento, il operator new[] di sovraccarico che è stato chiamato era:

void * __CRTDECL operator new[](::size_t count, const std::nothrow_t& x) 
_THROW0() 
{ // Try to allocate count bytes for an array 
    return (operator new(count, x)); 
} 

risposta

4

Domanda 1: Che cosa è successo esattamente quando ho aggiunto la linea di debug che risolto il problema? Suppongo che per qualche ragione il mio operatore delete [] non sia stato conosciuto come finché non l'ho chiamato nel mio codice applicazione? Questo è garantito per risolvere il problema o è solo una fortuna stupida?

§3.2 [basic.def.odr]/p4:

Una funzione di linea sono definite in ogni unità di traduzione in cui è ODR utilizzato.

Sembra che il compilatore non ha generato il codice per il mondiale operator delete[] poiché non è utilizzato nella vostra unità di traduzione principale ed è contrassegnato inline (il che significa che il compilatore può supporre che ogni unità di traduzione che utilizza li avranno un definizione di loro). Tuttavia, la libreria compilata separatamente non ha una definizione di tali funzioni e si finisce per utilizzare quelle predefinite dalla libreria standard. Rendendoli non- inline dovrebbe risolvere il problema.

Domanda 2: ho notato che il new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] non ha chiamato i miei operator new[] direttamente, ma alla fine chiamato il mio operator new (nessun parentesi).Chiama ancora l'operatore delete[] sul puntatore. questo pone un problema? Devo aggiungere il sovraccarico appropriato come che viene chiamato il mio operator new[] o questo comportamento è corretto?

Le versioni di default sia di lancio e nonthrowing versioni di operator new [], così come la versione nonthrowing di operator new, sono specificati per chiamare la versione di lancio operator new per ottenere la memoria. Quindi sei al sicuro lì. Tuttavia, le definizioni di operator new sono probabilmente sbagliate. Devono restituire un puntatore valido o generare un'eccezione. Restituire un puntatore nullo non è permesso.

+0

Rimozione in linea e inserimento del codice in un file di implementazione anziché l'intestazione funzionante! Mi chiedo perché il link da me copiato non ne abbia menzionato nulla. – DSM

Problemi correlati