Domanda

Io sono il mantenimento di un plugin (implementato come una dll) per un grande chiuso l'applicazione di origine.Questo ha funzionato bene per anni.Tuttavia, con l'ultimo aggiornamento è SDK di fornitore globale di overload degli operatori new e delete.Questo provoca un sacco di guai per me.Quello che succede è che il mio plugin assegna una stringa.Io passo questa stringa in una libreria collegata staticamente che la modifica (cambia quindi anche la ridistribuzione di esso).La mia applicazione si blocca.

Il motivo è, naturalmente, che la stringa di vita del fornitore assegnati personalizzato heap.La libreria collegata staticamente non sa nulla di questo mucchio e tenta di utilizzare l'impostazione predefinita new/delete operatori che di memoria.Boom.

Ora la domanda è:come posso mantenere il mio codice pulito ed evitare di usare il fornitore operatori?Non c'è nessun condizionale macro di preprocessore.Non posso evitare di includere offendere intestazione, in quanto contiene 2000 righe di codice mi serve per il plugin.Non posso passare la condizione allocatore nell'altra libreria dal momento che non fornisce meccanismi per che.Ho già ostacolato il venditore su di esso.Non so cos'altro potrei provare?

Addendum: Dopo discussioni sono riuscito a convincere il venditore a rimuovere i sovraccarichi di nuovo la prossima versione dell'SDK.Ho risolto il mio problema immediato, semplicemente di hacking l'attuale SDK e la rimozione di overload manualmente.Grazie per tutti i suggerimenti in questo thread.Hanno servito come argomenti e ulteriore "prova" del perché i sovraccarichi sono una cattiva idea, in primo luogo.

È stato utile?

Soluzione

Se si sta compilando in (via intestazione l'inclusione di un override/nuovo operatore delete(s), tutte le chiamate in codice per new/delete loro utilizzo.Non vi è alcun modo per ri-override (errori di collegamento) o solo parzialmente l'override, etc.

È cattiva forma per eseguire l'override del global new/delete operatori del settore, a tutti.E ' una cattiva idea.Se non capisci perché è una cattiva idea, non siete qualificati per farlo.Se ti rendi conto perché è una cattiva idea, sei qualificato per farlo, ma in genere scegliere di non.

La definizione di un global new/delete è esponenzialmente più male di un componente che si aspettano le persone a includere direttamente nel loro progetto.È il vostro lavoro come un cliente per aiutare il venditore a fare questo a capire la gravità della situazione, o smettere di essere loro cliente.

È possibile definire un allocatore personalizzato tipo (vedi questo link per un buon tutorial su come farlo, il bisogno di interfaccia, ecc) e utilizzare esclusivamente con il vostro STL tipi (è un argomento del modello).

Per shared_ptr, è necessario fare qualcosa di un po ' diverso:ci vuole un deleter oggetto come parametro al costruttore se non si desidera che il valore predefinito "delete p" comportamento.Questo non è un allocatore personalizzato;e ' solo un normale unario funtore.

Altri suggerimenti

Non è possibile fare questo:

namespace evil{

#include "evil_header.h"

}

Quindi cosa evil_header dichiara global new/delete diventa evil::nuovo/evil::delete.Dubito che giocare bene, se non ci sono di intestazione definizioni delle cose dichiarate in evil_header però.

È possibile utilizzare un altro nuovo spazio dei nomi:

namespace MyNS {
    // Declare your new/delete operators here
    // and also declare a class implementing the same interface as std::allocator
    // using your newly created memory management functions.
    // Don't forget to put all your classes in the namespace.
    // (if you don't have one already)
}

Il tuo grado di usare tutte le classi STL, dando loro il vostro allocatore tipo di modello argomento.

Una possibilità è quella di creare il proprio sovraccarico nuovo operatore che può essere implementato in termini di malloc.

Questo potrebbe essere definito come:

enum MyNew {EMyNew};

void *operator new(size_t size, MyNew);

Questo può quindi essere chiamato da voi MyClass* myClass = new (EMyNew)MyClass;

Dal momento che questo è implementato in termini di malloc, deve comportarsi come previsto.L'unico inconveniente è che dovrai sostituire tutte le istanze di cui hai usato di nuovo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top