Compartilhar via


Aviso do compilador (nível 1) C4291

'declaration': nenhuma exclusão de operador correspondente encontrada; a memória não será liberada se a inicialização gerar uma exceção

Um new de posicionamento é usado para o qual não há nenhum delete de posicionamento.

Quando a memória é alocada para um objeto com o operador new, o construtor do objeto é chamado. Se o construtor gerar uma exceção, qualquer memória alocada para o objeto deverá ser desalocada. Isso não pode ocorrer a menos que exista uma função de operador delete que corresponda ao operador new.

Se você usar o operador new sem nenhum argumento extra e o compilar com a opção /GX, /EHs ou /EHa, o compilador gerará um código para chamar o operador delete caso o construtor gere uma exceção.

Se você usar o formulário de posicionamento do operador new (o formulário com argumentos além do tamanho da alocação) e o construtor do objeto gerar uma exceção, o compilador ainda gerará código para chamar o operador delete; mas ele só o fará se existir um formulário de posicionamento do operador delete correspondente ao formulário de posicionamento do operador new que alocou a memória. Por exemplo:

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

O exemplo acima gera o aviso C4291 porque nenhum formulário de posicionamento do operador delete foi definido que corresponda ao formulário de posicionamento do operador new. Para resolver o problema, insira o código a seguir acima de main. Observe que todos os parâmetros de função do operador delete sobrecarregado correspondem aos do operador new sobrecarregado, exceto pelo primeiro parâmetro.

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