다음을 통해 공유


컴파일러 경고(수준 1) C4291

'declaration': 일치하는 연산자 삭제를 찾을 수 없습니다. 초기화에서 예외를 throw하면 메모리가 해제되지 않습니다.

배치 삭제가 없는 배치 항목이 사용됩니다.

연산 new자가 있는 개체에 대해 메모리가 할당되면 개체의 생성자가 호출됩니다. 생성자가 예외를 throw하는 경우 개체에 할당된 모든 메모리의 할당을 취소해야 합니다. 연산자 함수와 일치하는 new연산 delete 자 함수가 없으므로 이 작업을 수행할 수 없습니다.

추가 인수 없이 연산 new 자를 사용하고 /GX, /EHs 또는 /EHa 옵션으로 컴파일하여 예외 처리를 사용하도록 설정하는 경우 생성자가 예외를 throw하는 경우 컴파일러는 연산 delete 자를 호출하는 코드를 생성합니다.

연산자의 new 배치 형식(할당 크기 외에 인수가 있는 폼)을 사용하고 개체의 생성자가 예외를 throw하는 경우 컴파일러는 연산 delete자를 호출하는 코드를 생성하지만, 메모리를 할당한 연산 delete new 자의 배치 형식과 일치하는 배치 형식이 있는 경우에만 그렇게 합니다. 예시:

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

위의 예제에서는 연산자의 배치 형식new과 일치하는 연산 delete 자의 배치 형식이 정의되지 않아 경고 C4291을 생성합니다. 문제를 해결하려면 주 코드 위에 다음 코드를 삽입합니다. 오버로드된 모든 연산자 delete 함수 매개 변수는 첫 번째 매개 변수를 제외하고 오버로드된 연산자의 new매개 변수와 일치합니다.

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