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);
}