Avviso del compilatore (livello 1) C4291
'declaration': nessun operatore corrispondente eliminato; la memoria non verrà liberata se l'inizializzazione genera un'eccezione
Viene usato un nuovo posizionamento per il quale non è presente alcuna eliminazione di posizionamento.
Quando la memoria viene allocata per un oggetto con operatore new
, viene chiamato il costruttore dell'oggetto. Se il costruttore genera un'eccezione, qualsiasi memoria allocata per l'oggetto deve essere deallocata. Questa operazione non può essere eseguita a meno che non esista una funzione di operatore delete
corrispondente all'operatore new
.
Se si usa l'operatore new
senza argomenti aggiuntivi e si esegue la compilazione con le opzioni /GX, /EHs o /EHa per abilitare la gestione delle eccezioni, il compilatore genererà il codice per chiamare l'operatore delete
se il costruttore genera un'eccezione.
Se si utilizza il formato di posizionamento dell'operatore new
(il form con argomenti oltre alle dimensioni dell'allocazione) e il costruttore dell'oggetto genera un'eccezione, il compilatore genererà comunque il codice per chiamare l'operatore , ma lo farà solo se esiste una forma di posizionamento di operatore delete
corrispondente alla forma di posizionamento dell'operatore delete
new
che ha allocato la memoria. Ad esempio:
// C4291.cpp
// compile with: /EHsc /W1
#include <malloc.h>
class CList
{
public:
CList(int)
{
throw "Fail!";
}
};
void* operator new(size_t size, char* pszFilename, int nLine)
{
return malloc(size);
}
int main(void)
{
try
{
// This will call ::operator new(unsigned int) to allocate heap
// memory. Heap memory pointed to by pList1 will automatically be
// deallocated by a call to ::operator delete(void*) when
// CList::CList(int) throws an exception.
CList* pList1 = new CList(10);
}
catch (...)
{
}
try
{
// This will call the overloaded ::operator new(size_t, char*, int)
// to allocate heap memory. When CList::CList(int) throws an
// exception, ::operator delete(void*, char*, int) should be called
// to deallocate the memory pointed to by pList2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation cannot occur.
CList* pList2 = new(__FILE__, __LINE__) CList(20); // C4291
}
catch (...)
{
}
}
L'esempio precedente genera l'avviso C4291 perché non è stata definita alcuna forma di posizionamento dell'operatore delete
che corrisponde al formato di posizionamento dell'operatore new
. Per risolvere il problema, inserire il codice seguente sopra main. Si noti che tutti i parametri della funzione dell'operatore delete
di overload corrispondono a quelli dell'operatore new
di overload , ad eccezione del primo parametro.
void operator delete(void* pMem, char* pszFilename, int nLine)
{
free(pMem);
}