Durante la lettura delle risposte a this question ho notato che le risposte (this per esempio) implicano che operator delete
può essere chiamato anche quando l'istruzione delete
viene eseguita su un puntatore nullo.Perché "operator delete" viene richiamato quando chiamo "delete" su un puntatore nullo?
così ho scritto un piccolo frammento:
class Test {
public:
void* operator new(size_t) { /*doesn't matter*/ return 0; }
void operator delete(void* ptr) {
ptr; //to suppress warning and have a line to put breakpoint on
}
};
int main()
{
Test* ptr = 0;
delete ptr;
}
e - sorprendentemente per me - Test::operator delete()
viene richiamato con ptr
in possesso di un puntatore nullo.
Come ho capito, operator new
alloca la memoria e operator delete
restituisce la memoria all'allocatore. Se chiamo l'istruzione delete
su un puntatore nullo significa che non c'era alcun oggetto dietro il puntatore e che non c'è memoria per tornare all'allocatore.
delete
include il richiamo di un distruttore. Quando passo un puntatore nullo il distruttore non è sicuramente invocato - C++ si prende cura di questo. Allora perché è invocato lo operator delete
in questo caso?
Chiedere anche perché viene richiamato 'operator new' quando si assegna un array di lunghezza zero:' new Test [0]; '...;) – ybungalobill
@ybungalobill: È più semplice: lo standard richiede che il puntatore restituito sia valido e distinto . – sharptooth
Si noti che se si rende virtuale il distruttore, l'overload 'operator delete' non verrà chiamato. Le implementazioni solitamente invocano la funzione direttamente dal distruttore e chiamano il distruttore senza un controllo per null (risparmiando così poche istruzioni). Solo quando la chiamata ha bisogno di invio virtuale è il controllo eseguito in anticipo. – avakar