Compartir a través de


Advertencia del compilador (nivel 1) C4291

"declaration": no se ha encontrado un operador delete que coincida; no se liberará memoria si la inicialización genera una excepción

Observaciones

Se usa un operador de ubicación new para el que no hay operador de ubicación delete.

Cuando se asigna memoria para un objeto con el operador new, se llama al constructor del objeto. Si el constructor genera una excepción, se debe desasignar la memoria que se asignó para el objeto. Esto no puede ocurrir a menos que exista una función de operador delete que coincida con el operador new.

Si usa el operador new sin ningún argumento adicional y compila con las opciones /GX, /EHs o /EHa para habilitar el control de excepciones, el compilador generará código para llamar al operador delete si el constructor genera una excepción.

Si se usa el formato de ubicación del operador new (el formato con argumentos además del tamaño de la asignación) y el constructor del objeto genera una excepción, el compilador de todos modos generará código para llamar al operador delete, pero solo lo hará si existe un formato de ubicación del delete que coincide con el formato de ubicación del operador new que asignó la memoria.

Example

Por ejemplo:

// 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 (...)
   {
   }
}

En el ejemplo anterior, se genera la advertencia C4291 porque no se ha definido ningún formato de ubicación del operador delete que coincida con el formato de ubicación del operador new. Para solucionar el problema, inserte el código siguiente sobre main. Tenga en cuenta que todos los parámetros de la función del operador sobrecargado delete coinciden con los del operador sobrecargado new, excepto para el primer parámetro.

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