Condividi tramite


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 deletenew 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 newdi overload , ad eccezione del primo parametro.

void operator delete(void* pMem, char* pszFilename, int nLine)
{
   free(pMem);
}