Upozornění kompilátoru (úroveň 1) C4291
"deklarací" : nebyl nalezen žádný odpovídající operátor, který by odstranil; paměť se neuvolní, pokud inicializace vyvolá výjimku
Použije se nové umístění, pro které neexistuje odstranění umístění.
Při přidělení paměti pro objekt s operátorem new
, je volána konstruktor objektu. Pokud konstruktor vyvolá výjimku, měla by být uvolněna veškerá paměť přidělená objektu. K tomu nelze dojít, pokud neexistuje funkce operátoru delete
, která odpovídá operátoru new
.
Pokud použijete operátor new
bez dalších argumentů a zkompilujete s možnostmi /GX, /EHs nebo /EHa pro povolení zpracování výjimek, kompilátor vygeneruje kód pro volání operátoru delete
, pokud konstruktor vyvolá výjimku.
Pokud použijete formu umístění operátoru new
(formulář s argumenty kromě velikosti přidělení) a konstruktor objektu vyvolá výjimku, kompilátor stále vygeneruje kód pro volání operátoru delete
; ale provede to pouze v případě, že existuje forma umístění operátoru delete
odpovídající formuláři umístění operátoru new
, který přidělil paměť. Příklad:
// 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 (...)
{
}
}
Výše uvedený příklad generuje upozornění C4291, protože nebyla definována žádná forma umístění operátoru delete
, která odpovídá formě umístění operátoru new
. Chcete-li tento problém vyřešit, vložte následující kód nad hlavní. Všimněte si, že všechny parametry přetížené funkce operátoru delete
odpovídají parametrům přetíženého operátoru new
s výjimkou prvního parametru.
void operator delete(void* pMem, char* pszFilename, int nLine)
{
free(pMem);
}