본문 바로가기

Programming/C & C++

Detecting Memory Leaks with std::nothrow

메모리 누수 체크와 nothrow를 같이 쓰는 방법이다.

// 메모리 누수 체크 클래스
class DetectMemoryLeaks
{
private:
	bool m_bDetail;
public:
	DetectMemoryLeaks( bool _bDetail ) : m_bDetail( _bDetail )
	{ 
		_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
	}

	~DetectMemoryLeaks()
	{
		if( m_bDetail == true )
		{
			TRACE( "--- Detailed Memory Detection ---\n" );
			_CrtMemState s1;
			_CrtMemCheckpoint( &s1 );
			_CrtMemDumpStatistics( &s1 );
		}
		else
		{
			TRACE( "--- Memory Check ---\n" );
		}
	}
	DetectMemoryLeaks( bool _bDetail ) : m_bDetail( _bDetail ){};
	~DetectMemoryLeaks(){};
};

DetectMemoryLeaks는 static class DetectMemoryLeaks으로 선언해도 된다. (나는 추가적인 입력값을 받아서 메모리 누수를 체크할 지 안할지를 정할 수 있게 했기 때문에 static처리를 하지 않았다.)

 

#include<new>
#if defined( _DEBUG )
#	if defined(__cplusplus)
#		define _CRTDBG_MAP_ALLOC
#		define CRTDBG_MAP_ALLOC
#		define malloc( s ) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
		inline void* operator new( size_t _size, int _BlockUse, char const* _FileName, int _LineNumber, std::nothrow_t )
		{
			void* ptr = nullptr;
			try
			{
				ptr = _malloc_dbg( _size, _BlockUse,_FileName, _LineNumber );
				if( !ptr ) throw std::bad_alloc(); // 메모리 할당 실패 시 예외 던지기
			}
			catch( const std::bad_alloc& ) { return nullptr; }
			return ptr;
		}
		inline void operator delete( void* _Block, int _BlockUse, char const* _FileName, int _LineNumber, std::nothrow_t ) noexcept
		{
			std::free( _Block );
		}
#		define new( _throw )	new( _NORMAL_BLOCK, __FILE__, __LINE__, _throw )
#	endif
#endif

전역으로 operator new를 정의한다(header에서 정의하기 때문에 inline 처리)

맨 마지막에 std::nothrow_t를 추가했다.

class TestClass
{
public:
	int a ;
	TestClass():a(0){};
	~TestClass(){};
};

void TestField_Main()
{
	TestClass* a5 = new (std::nothrow) TestClass;
	return;
}