Compilerwarnung (Stufe 1) C4291

Aktualisiert: November 2007

Fehlermeldung

'Deklaration': Kein zugehöriger delete-Operator gefunden; Speicher wird nicht freigegeben, wenn die Initialisierung eine Ausnahme auslöst
'declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception

Es wird eine new-Positionierung verwendet, für die keine delete-Positionierung vorhanden ist.

Wenn mit dem new-Operator Arbeitsspeicher für ein Objekt reserviert wird, wird der Konstruktor des Objekts aufgerufen. Wenn der Konstruktor eine Ausnahme auslöst, sollte die Reservierung des gesamten für ein Objekt reservierten Speichers aufgehoben werden. Dies ist jedoch nur möglich, wenn für den new-Operator der entsprechende delete-Operator vorhanden ist.

Wenn Sie den new-Operator ohne zusätzliche Argumente verwenden und die Kompilierung mit den Optionen /GX, /EHs oder /EHa durchführen, um die Ausnahmebehandlung zu aktivieren, generiert der Compiler Code, durch den der delete-Operator aufgerufen wird, sobald der Konstruktor eine Ausnahme auslöst.

Wenn Sie die Positionierungsform des new-Operators verwenden (ein Format, das neben der Reservierungsgröße auch Argumente enthält) und der Konstruktor des Objekts eine Ausnahme auslöst, generiert der Compiler nach wie vor Code zum Aufrufen des delete-Operators. Dies ist jedoch nur der Fall, wenn eine Positionierungsform des delete-Operators vorhanden ist, die der Positionierungsform des new-Operators entspricht, durch den Arbeitsspeicher reserviert wurde. Beispiel:

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

Durch das vorangehende Beispiel wird die Warnung C4291 generiert, da keine Positionierungsform des delete-Operators definiert wurde, die mit der Positionierungsform des new-Operators übereinstimmt. Um das Problem zu beheben, fügen Sie folgenden Code oberhalb von main ein. Beachten Sie, dass alle Funktionsparameter des überladenen delete-Operators – mit Ausnahme des ersten Parameters – mit denen des überladenen new-Operators übereinstimmen.

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