진단 서비스

MFC 라이브러리는 프로그램을 더 쉽게 디버그할 수 있는 많은 진단 서비스를 제공합니다. 이러한 진단 서비스에는 매크로 및 전역 함수가 포함되며, 이러한 함수를 통해 프로그램의 메모리 할당을 추적하고 런타임 중 개체의 내용을 덤프하고 런타임 중 디버깅 메시지를 인쇄할 수 있습니다. 진단 서비스의 매크로 및 전역 함수는 다음과 같은 범주로 그룹화됩니다.

  • 일반 진단 매크로

  • 일반 진단 함수 및 변수

  • 개체 진단 함수

이러한 매크로 및 함수는 MFC 디버그 및 릴리스 버전의 CObject 에서 파생된 모든 클래스에서 사용할 수 있습니다. 그러나 DEBUG_NEW 및 VERIFY를 제외한 모든 작업은 릴리스 버전에서 아무 것도 수행하지 않습니다.

디버그 라이브러리에서 할당된 모든 메모리 블록은 일련의 "가드 바이트"로 괄호로 묶입니다. 이러한 바이트가 잘못된 메모리 쓰기로 인해 방해를 받는 경우 진단 루틴에서 문제를 보고할 수 있습니다. 다음 줄을 포함하는 경우

#define new DEBUG_NEW

구현 파일에서 모든 호출 new 은 메모리 할당이 발생한 파일 이름과 줄 번호를 저장합니다. CMemoryState::DumpAllObjectsSince 함수는 이 추가 정보를 표시하여 메모리 누수를 확인할 수 있도록 합니다. 또한 진단 출력에 대한 자세한 내용은 CDumpContext 클래스를 참조하세요.

또한 C 런타임 라이브러리는 애플리케이션을 디버그하는 데 사용할 수 있는 진단 함수 집합도 지원합니다. 자세한 내용은 런타임 라이브러리 참조에서 루틴 디버그 를 참조하세요.

MFC 일반 진단 매크로

이름 설명
ASSERT 라이브러리의 디버그 버전에서 지정된 식의 값이 FALSE 로 계산된 경우 메시지를 출력한 후 프로그램을 중단합니다.
ASSERT_KINDOF 개체가 지정된 클래스의 개체인지 아니면 지정된 클래스에서 파생된 클래스의 개체인지 테스트합니다.
ASSERT_VALID 해당 AssertValid 멤버 함수를 호출하여 개체의 내부 유효성을 테스트합니다. 일반적으로 CObject에서 재정의됩니다.
DEBUG_NEW 메모리 누수를 쉽게 찾을 수 있도록 디버그 모드에서 모든 개체 할당에 파일 이름과 줄 번호를 제공합니다.
DEBUG_ONLY ASSERT 와 비슷하지만, 식의 값을 테스트하지는 않습니다. 디버그 모드에서만 실행해야 하는 코드에 유용합니다.
확인 및 ENSURE_VALID 데이터 정확성의 유효성을 검사하는 데 사용합니다.
THIS_FILE 컴파일 중인 파일의 이름으로 확장합니다.
TRACE 라이브러리의 디버그 버전에서 printf와 유사한 기능을 제공합니다.
VERIFY ASSERT 와 비슷하지만, 라이브러리의 릴리스 버전뿐만 아니라 디버그 버전에서도 식을 계산합니다.

MFC 일반 진단 변수 및 함수

이름 설명
afxDump CDumpContext 정보를 디버거 출력 창 또는 디버그 터미널에 보내는 전역 변수입니다.
afxMemDF 디버깅 메모리 할당자의 동작을 제어하는 전역 변수입니다.
AfxCheckError 전달된 SCODE 를 테스트하여 오류인지 알아보고 오류인 경우 적절한 오류를 throw하는 데 사용하는 전역 변수입니다.
AfxCheckMemory 현재 할당된 모든 메모리의 무결성을 검사합니다.
AfxDebugBreak 실행 중단을 발생합니다.
AfxDump 디버거 내에 있는 동안 호출되는 경우 디버그하는 동안 개체의 상태를 덤프합니다.
AfxDump 디버깅하는 동안 개체의 상태를 덤프하는 내부 함수입니다.
AfxDumpStack 현재 스택의 이미지를 생성합니다. 이 함수는 항상 정적으로 연결됩니다.
AfxEnableMemoryLeakDump 메모리 누수 덤프를 사용하도록 설정합니다.
AfxEnableMemoryTracking 메모리 추적을 켜고 끕니다.
AfxIsMemoryBlock 메모리 블록이 제대로 할당되었는지 확인합니다.
AfxIsValidAddress 메모리 주소 범위가 프로그램의 경계 내에 있는지 확인합니다.
AfxIsValidString 문자열에 대한 포인터가 유효한지 여부를 결정합니다.
AfxSetAllocHook 각 메모리 할당에서 함수 호출을 사용하도록 설정합니다.

MFC 개체 진단 함수

이름 설명
AfxDoForAllClasses 런타임 형식 검사를 지원하는 모든 CObject파생 클래스에서 지정된 함수를 실행합니다.
AfxDoForAllObjects 와 함께 할당된 모든 CObject파생 개체에 대해 지정된 함수를 new수행합니다.

MFC 컴파일 매크로

이름 설명
_AFX_SECURE_NO_WARNINGS 사용되지 않는 MFC 함수 사용에 대한 컴파일러 경고를 표시하지 않습니다.

_AFX_SECURE_NO_WARNINGS

사용되지 않는 MFC 함수 사용에 대한 컴파일러 경고를 표시하지 않습니다.

구문

_AFX_SECURE_NO_WARNINGS

예시

이 코드 샘플은 정의되지 않은 경우 _AFX_SECURE_NO_WARNINGS 컴파일러 경고를 발생합니다.

// define this before including any afx files in *pch.h* (*stdafx.h* in Visual Studio 2017 and earlier)
#define _AFX_SECURE_NO_WARNINGS

// . . .

CRichEditCtrl* pRichEdit = new CRichEditCtrl;
pRichEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
   CRect(10,10,100,200), pParentWnd, 1);
char sz[256];
pRichEdit->GetSelText(sz);

AfxDebugBreak

이 함수를 호출하여 MFC 애플리케이션의 디버그 버전 실행 시 중단(호출 AfxDebugBreak위치)을 발생시킬 수 있습니다.

구문

void AfxDebugBreak( );

설명

AfxDebugBreak 는 MFC 애플리케이션의 릴리스 버전에 영향을 주지 않으며 제거해야 합니다. 이 함수는 MFC 애플리케이션에서만 사용해야 합니다. Win32 API 버전을 DebugBreak사용하여 MFC가 아닌 애플리케이션에서 중단을 발생합니다.

요구 사항

헤더: afxver_.h

ASSERT

인수를 평가합니다.

ASSERT(booleanExpression)

매개 변수

booleanExpression
0이 아닌 값 또는 0으로 계산되는 식(포인터 값 포함)을 지정합니다.

설명

결과가 0이면 매크로가 진단 메시지를 출력하고 프로그램을 중단합니다. 조건이 0이 아닌 경우 아무 것도 수행하지 않습니다.

진단 메시지의 형식은 다음과 같습니다.

assertion failed in file <name> in line <num>

여기서 이름은 원본 파일의 이름이고 num 은 원본 파일에서 실패한 어설션의 줄 번호입니다.

MFC의 릴리스 버전에서 ASSERT는 식을 평가하지 않으므로 프로그램을 중단하지 않습니다. 환경에 관계없이 식을 평가해야 하는 경우 ASSERT 대신 VERIFY 매크로를 사용합니다.

참고 항목

이 함수는 디버그 버전의 MFC에서만 사용할 수 있습니다.

예시

CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(pcage != NULL);
ASSERT(pcage->IsKindOf(RUNTIME_CLASS(CAge)));
// Terminates program only if pcage is NOT a CAge*.   

요구 사항

헤더: afx.h

ASSERT_KINDOF

이 매크로는 지정한 개체가 지정된 클래스의 개체이거나 지정된 클래스에서 파생된 클래스의 개체임을 어설션합니다.

ASSERT_KINDOF(classname, pobject)

매개 변수

classname
파생 클래스의 CObject이름입니다.

pobject
클래스 개체에 대한 포인터입니다.

설명

pobject 매개 변수는 개체에 대한 포인터여야 하며 const. 가리키는 개체이며 클래스는 런타임 클래스 정보를 지원 CObject 해야 합니다. 예를 들어 클래스의 CMyDoc 개체 또는 파생 개체에 대한 포인터인지 확인 pDocument 하려면 다음을 코딩할 수 있습니다.

ASSERT_KINDOF(CMyDoc, pDocument);

매크로 사용 ASSERT_KINDOF 은 코딩과 똑같습니다.

ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));

이 함수는 [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic 또는 DECLARE_SERIAL 매크로로 선언된 클래스에 대해서만 작동합니다.

참고 항목

이 함수는 디버그 버전의 MFC에서만 사용할 수 있습니다.

요구 사항

헤더: afx.h

ASSERT_VALID

개체의 내부 상태의 유효성에 대한 가정을 테스트하는 데 사용합니다.

ASSERT_VALID(pObject)

매개 변수

pObject
멤버 함수의 재정의 버전이 있는 클래스에서 CObject 파생된 개체를 AssertValid 지정합니다.

설명

ASSERT_VALID 인수로 전달된 개체의 멤버 함수를 호출 AssertValid 합니다.

MFC 릴리스 버전에서는 ASSERT_VALID 아무 것도 수행하지 않습니다. 디버그 버전에서는 포인터의 유효성을 검사하고 NULL에 대해 검사 개체의 자체 AssertValid 멤버 함수를 호출합니다. 이러한 테스트가 실패하면 경고 메시지가 ASSERT와 동일한 방식으로 표시됩니다.

참고 항목

이 함수는 디버그 버전의 MFC에서만 사용할 수 있습니다.

자세한 내용 및 예제는 MFC 애플리케이션 디버깅을 참조 하세요.

예시

// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);

요구 사항

헤더: afx.h

DEBUG_NEW

메모리 누수 찾기를 지원합니다.

#define  new DEBUG_NEW

설명

일반적으로 연산자를 사용하여 힙 스토리지를 할당하는 프로그램의 모든 위치에서 DEBUG_NEW 사용할 new 수 있습니다.

디버그 모드에서( _DEBUG 기호가 정의되면) DEBUG_NEW 할당하는 각 개체의 파일 이름과 줄 번호를 추적합니다. 그런 다음 CMemoryState::D umpAllObjectsSince 멤버 함수를 사용하면 DEBUG_NEW 할당된 각 개체가 할당된 파일 이름 및 줄 번호와 함께 표시됩니다.

DEBUG_NEW 사용하려면 소스 파일에 다음 지시문을 삽입합니다.

#define new DEBUG_NEW

이 지시문을 삽입하면 전처리기는 모든 new위치에서 DEBUG_NEW 삽입하고 MFC는 나머지를 수행합니다. 프로그램의 릴리스 버전을 컴파일할 때 DEBUG_NEW 간단한 new 작업으로 확인되고 파일 이름 및 줄 번호 정보가 생성되지 않습니다.

참고 항목

이전 버전의 MFC(4.1 이하)에서는 IMPLEMENT_DYNCREATE 또는 IMPLEMENT_SERIAL 매크로를 호출한 모든 문 뒤의 문을 배치 #define 해야 했습니다. 이는 더 이상 필요하지 않습니다.

요구 사항

헤더: afx.h

DEBUG_ONLY

디버그 모드에서(_DEBUG 기호가 정의된 경우) DEBUG_ONLY 해당 인수를 평가합니다.

DEBUG_ONLY(expression)

설명

릴리스 빌드에서 DEBUG_ONLY 해당 인수를 평가하지 않습니다. 디버그 빌드에서만 실행해야 하는 코드가 있는 경우에 유용합니다.

DEBUG_ONLY 매크로는 주변 #ifdef _DEBUG#endif같습니다.

예시

void ExampleFunc(char* p, int size, char fill)
{
   char* q;               // working copy of pointer 
   VERIFY(q = p);         // copy buffer pointer and validate
   ASSERT(size >= 100);   // make sure buffer is at least 100 bytes
   ASSERT(isalpha(fill)); // make sure fill character is alphabetic
   // if fill character is invalid, substitute 'X' so we can continue
   // debugging after the preceding ASSERT fails.
   DEBUG_ONLY(fill = (isalpha(fill)) ? fill : 'X');
}

요구 사항

헤더: afx.h

확인 및 ENSURE_VALID

데이터 정확성의 유효성을 검사하는 데 사용합니다.

구문

ENSURE(  booleanExpression )
ENSURE_VALID( booleanExpression  )

매개 변수

booleanExpression
테스트할 부울 식을 지정합니다.

설명

이러한 매크로의 목적은 매개 변수의 유효성 검사를 개선하는 것입니다. 매크로는 코드에서 잘못된 매개 변수의 추가 처리를 방지합니다. ASSERT 매크로와 달리 ENSURE 매크로는 어설션 생성 외에도 예외를 throw합니다.

매크로는 프로젝트 구성에 따라 두 가지 방법으로 동작합니다. 매크로는 ASSERT를 호출한 다음 어설션이 실패하면 예외를 throw합니다. 따라서 디버그 구성(즉, _DEBUG 정의된 경우)에서 매크로는 어설션 및 예외를 생성하고 릴리스 구성에서는 매크로가 예외만 생성합니다(ASSERT는 릴리스 구성에서 식을 평가하지 않음).

매크로 ENSURE_ARG ENSURE 매크로처럼 작동합니다.

ENSURE_VALID ASSERT_VALID 매크로를 호출합니다(디버그 빌드에만 적용됨). 또한 포인터가 NULL인 경우 ENSURE_VALID 예외를 throw합니다. NULL 테스트는 디버그 및 릴리스 구성 모두에서 수행됩니다.

이러한 테스트가 실패하면 경고 메시지가 ASSERT와 동일한 방식으로 표시됩니다. 필요한 경우 매크로가 잘못된 인수 예외를 throw합니다.

요구 사항

헤더: afx.h

THIS_FILE

컴파일 중인 파일의 이름으로 확장합니다.

구문

THIS_FILE

설명

이 정보는 ASSERT 및 VERIFY 매크로에서 사용됩니다. 애플리케이션 마법사 및 코드 마법사는 만든 소스 코드 파일에 매크로를 배치합니다.

예시

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// __FILE__ is one of the six predefined ANSI C macros that the
// compiler recognizes.

요구 사항

헤더: afx.h

TRACE

지정된 문자열을 현재 애플리케이션의 디버거로 보냅니다.

TRACE(exp)
TRACE(DWORD  category,  UINT  level, LPCSTR lpszFormat, ...)

설명

TRACE에 대한 설명은 ATLTRACE2 참조하세요. TRACE 및 ATLTRACE2 동작이 동일합니다.

MFC의 디버그 버전에서 이 매크로는 지정된 문자열을 현재 애플리케이션의 디버거로 보냅니다. 릴리스 빌드에서 이 매크로는 아무 것도 컴파일하지 않습니다(코드가 전혀 생성되지 않음).

자세한 내용은 MFC 애플리케이션 디버깅을 참조 하세요.

요구 사항

헤더: afx.h

VERIFY

MFC의 디버그 버전에서 해당 인수를 평가합니다.

VERIFY(booleanExpression)

매개 변수

booleanExpression
0이 아닌 값 또는 0으로 계산되는 식(포인터 값 포함)을 지정합니다.

설명

결과가 0이면 매크로가 진단 메시지를 출력하고 프로그램을 중지합니다. 조건이 0이 아닌 경우 아무 것도 수행하지 않습니다.

진단 메시지의 형식은 다음과 같습니다.

assertion failed in file <name> in line <num>

여기서 이름은 원본 파일의 이름이고 num 은 원본 파일에서 실패한 어설션의 줄 번호입니다.

MFC의 릴리스 버전에서 VERIFY는 식을 평가하지만 프로그램을 인쇄하거나 중단하지는 않습니다. 예를 들어 식이 함수 호출인 경우 호출이 이루어집니다.

예시

// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system.

// It _is_ possible that GetDC() may fail, but the out-of-memory
// condition that causes it isn't likely. For a test application,
// this use of VERIFY() is fine. For any production code, this
// usage is dubious.

// get the display device context
HDC hdc;
VERIFY((hdc = ::GetDC(hwnd)) != NULL);

// give the display context back
::ReleaseDC(hwnd, hdc);

요구 사항

헤더: afx.h

afxDump(MFC의 CDumpContext)

애플리케이션에서 기본 개체 덤프 기능을 제공합니다.

CDumpContext  afxDump;

설명

afxDump는 디버거 출력 창 또는 디버그 터미널에 CDumpContext 정보를 보낼 수 있도록 하는 미리 정의 된 CDumpContext 개체입니다. 일반적으로 .에 대한 매개 변수CObject::Dump로 제공합니다afxDump.

Windows NT 및 모든 버전의 Windows afxDump 에서 애플리케이션을 디버그할 때 출력이 Visual C++의 출력-디버그 창으로 전송됩니다.

이 변수는 디버그 버전의 MFC에서만 정의됩니다. 자세한 내용은 afxDumpMFC 애플리케이션 디버깅을 참조 하세요.

예시

// example for afxDump
CPerson* pMyPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << _T("Dumping myPerson:\n");
pMyPerson->Dump(afxDump);
afxDump << _T("\n");
#endif

요구 사항

헤더: afx.h

AfxDump(내부)

MFC가 디버깅하는 동안 개체의 상태를 덤프하는 데 사용하는 내부 함수입니다.

구문

void AfxDump(const CObject* pOb);

매개 변수

pOb
에서 파생된 CObject클래스의 개체에 대한 포인터입니다.

설명

AfxDump 는 개체의 Dump 멤버 함수를 호출하고 변수에 지정된 afxDump 위치로 정보를 보냅니다. AfxDump 는 MFC의 디버그 버전에서만 사용할 수 있습니다.

프로그램 코드는 호출 AfxDump하지 말고 대신 적절한 개체의 Dump 멤버 함수를 호출해야 합니다.

요구 사항

헤더: afx.h

afxMemDF

이 변수는 디버거 또는 프로그램에서 액세스할 수 있으며 할당 진단 조정할 수 있습니다.

int  afxMemDF;

설명

afxMemDF는 열거형에 지정된 대로 다음 값을 가질 수 있습니다.afxMemDF

  • allocMemDF 디버깅 할당자를 켭니다(디버그 라이브러리의 기본 설정).

  • delayFreeMemDF 메모리 해제를 지연합니다. 프로그램에서 메모리 블록을 해제하는 동안 할당자는 해당 메모리를 기본 운영 체제로 반환하지 않습니다. 그러면 프로그램에 최대 메모리 스트레스가 발생합니다.

  • checkAlwaysMemDF 메모리가 할당되거나 해제될 때마다 호출 AfxCheckMemory 합니다. 이렇게 하면 메모리 할당 및 할당 취소 속도가 크게 느려집니다.

예시

afxMemDF = allocMemDF | checkAlwaysMemDF;

요구 사항

헤더: afx.h

AfxCheckError

이 함수는 전달된 SCODE를 테스트하여 오류인지 확인합니다.

void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*

설명

오류가 발생하면 함수는 예외를 throw합니다. 전달된 SCODE가 E_OUTOFMEMORY 경우 함수는 AfxThrowMemoryException을 호출하여 CMemoryException을 throw합니다. 그렇지 않으면 함수는 AfxThrowOleException을 호출하여 COleException을 throw합니다.

이 함수는 애플리케이션에서 OLE 함수에 대한 호출의 반환 값을 검사 데 사용할 수 있습니다. 애플리케이션에서 이 함수를 사용하여 반환 값을 테스트하면 최소한의 코드로 오류 조건에 적절하게 대응할 수 있습니다.

참고 항목

이 함수는 디버그 및 비 디버그 빌드에서 동일한 효과를 줍니다.

예시

AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
   IID_IDispatch, (LPVOID*)& pWMPDispatch));

oddWMP.AttachDispatch(pWMPDispatch, TRUE);

요구 사항

헤더: afx.h

AfxCheckMemory

이 함수는 사용 가능한 메모리 풀의 유효성을 검사하고 필요에 따라 오류 메시지를 출력합니다.

BOOL  AfxCheckMemory();

Return Value

메모리 오류가 없으면 0이 아닙니다. 그렇지 않으면 0입니다.

설명

함수가 메모리 손상을 감지하지 않으면 아무 것도 출력하지 않습니다.

현재 힙에 할당된 모든 메모리 블록은 malloc 함수 또는 GlobalAlloc Windows 함수와 같은 기본 메모리 할당자에 대한 직접 호출에 의해 할당 new 된 메모리 블록을 포함하여 검사. 블록이 손상된 것으로 확인되면 메시지가 디버거 출력에 출력됩니다.

줄을 포함하는 경우

#define new DEBUG_NEW

프로그램 모듈에서 다음으로 호출하여 AfxCheckMemory 메모리가 할당된 파일 이름 및 줄 번호를 표시합니다.

참고 항목

모듈에 직렬화 가능한 클래스의 구현이 하나 이상 포함된 경우 마지막 IMPLEMENT_SERIAL 매크로 호출 다음에 줄을 배치 #define 해야 합니다.

이 함수는 MFC의 디버그 버전에서만 작동합니다.

예시

CAge* pcage = new CAge(21);  // CAge is derived from CObject.
Age* page = new Age(22);     // Age is NOT derived from CObject.
*(((char*)pcage) - 1) = 99;   // Corrupt preceding guard byte
*(((char*)page) - 1) = 99;    // Corrupt preceding guard byte
AfxCheckMemory();

요구 사항

헤더: afx.h

AfxDump(MFC)

디버거에 있는 동안 이 함수를 호출하여 디버깅하는 동안 개체의 상태를 덤프합니다.

void AfxDump(const CObject* pOb);

매개 변수

pOb
에서 파생된 CObject클래스의 개체에 대한 포인터입니다.

설명

AfxDump 는 개체의 Dump 멤버 함수를 호출하고 변수에 지정된 afxDump 위치로 정보를 보냅니다. AfxDump 는 MFC의 디버그 버전에서만 사용할 수 있습니다.

프로그램 코드는 호출 AfxDump하지 말고 대신 적절한 개체의 Dump 멤버 함수를 호출해야 합니다.

요구 사항

헤더: afx.h

AfxDumpStack

이 전역 함수를 사용하여 현재 스택의 이미지를 생성할 수 있습니다.

void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);

매개 변수

dwTarget
덤프 출력의 대상을 나타냅니다. 비트 OR(|) 연산자를 사용하여 결합할 수 있는 가능한 값은 다음과 같습니다.

  • AFX_STACK_DUMP_TARGET_TRACE TRACE 매크로를 사용하여 출력을 보냅니다. TRACE 매크로는 디버그 빌드에서만 출력을 생성합니다. 릴리스 빌드에서 출력을 생성하지 않습니다. 또한 TRACE는 디버거 외에 다른 대상으로 리디렉션될 수 있습니다.

  • AFX_STACK_DUMP_TARGET_DEFAULT 덤프 출력을 기본 대상으로 보냅니다. 디버그 빌드의 경우 출력은 TRACE 매크로로 이동합니다. 릴리스 빌드에서 출력은 클립보드로 이동합니다.

  • AFX_STACK_DUMP_TARGET_CLIPBOARD 출력을 클립보드로만 보냅니다. 데이터는 CF_TEXT 클립보드 형식을 사용하여 클립보드에 일반 텍스트로 배치됩니다.

  • AFX_STACK_DUMP_TARGET_BOTH 출력을 클립보드와 TRACE 매크로로 동시에 보냅니다.

  • AFX_STACK_DUMP_TARGET_ODS Win32 함수 OutputDebugString()를 통해 디버거에 직접 출력을 보냅니다. 이 옵션은 디버거가 프로세스에 연결될 때 디버그 및 릴리스 빌드 모두에서 디버거 출력을 생성합니다. AFX_STACK_DUMP_TARGET_ODS 항상 디버거에 도달하고(연결된 경우) 리디렉션할 수 없습니다.

설명

아래 예제에서는 MFC 대화 애플리케이션의 단추 처리기에서 호출 AfxDumpStack 하여 생성된 출력의 한 줄을 반영합니다.

=== begin AfxDumpStack output ===
00427D55: DUMP2\DEBUG\DUMP2.EXE! void AfxDumpStack(unsigned long) + 181 bytes
0040160B: DUMP2\DEBUG\DUMP2.EXE! void CDump2Dlg::OnClipboard(void) + 14 bytes
0044F884: DUMP2\DEBUG\DUMP2.EXE! int _AfxDispatchCmdMsg(class CCmdTarget *,
unsigned int,int,void ( CCmdTarget::*)(void),void *,unsigned int,struct
AFX_CMDHANDLE
0044FF7B: DUMP2\DEBUG\DUMP2.EXE! virtual int CCmdTarget::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 626 bytes
00450C71: DUMP2\DEBUG\DUMP2.EXE! virtual int CDialog::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 36 bytes
00455B27: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnCommand(unsigned
int,long) + 312 bytes
00454D3D: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnWndMsg(unsigned
int,unsigned int,long,long *) + 83 bytes
00454CC0: DUMP2\DEBUG\DUMP2.EXE! virtual long CWnd::WindowProc(unsigned
int,unsigned int,long) + 46 bytes
004528D9: DUMP2\DEBUG\DUMP2.EXE! long AfxCallWndProc(class CWnd *,struct
HWND__ *,unsigned int,unsigned int,long) + 237 bytes
00452D34: DUMP2\DEBUG\DUMP2.EXE! long AfxWndProc(struct HWND__ *,unsigned
int,unsigned int,long) + 129 bytes
BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes
BFF928E0: WINDOWS\SYSTEM\KERNEL32.DLL! UTUnRegister + 2492 bytes
=== end AfxDumpStack() output ===

위의 출력의 각 줄은 마지막 함수 호출의 주소, 함수 호출을 포함하는 모듈의 전체 경로 이름 및 호출된 함수 프로토타입을 나타냅니다. 스택의 함수 호출이 함수의 정확한 주소에서 발생하지 않으면 바이트 오프셋이 표시됩니다.

예를 들어 다음 표에서는 위 출력의 첫 번째 줄을 설명합니다.

출력 설명
00427D55: 마지막 함수 호출의 반환 주소입니다.
DUMP2\DEBUG\DUMP2.EXE! 함수 호출을 포함하는 모듈의 전체 경로 이름입니다.
void AfxDumpStack(unsigned long) 함수 프로토타입이 호출되었습니다.
+ 181 bytes 함수 프로토타입의 주소에서 반환 주소(이 경우void AfxDumpStack(unsigned long)00427D55)까지의 오프셋(바이트)입니다.

AfxDumpStack 는 MFC 라이브러리의 디버그 및 비데버그 버전에서 사용할 수 있습니다. 그러나 실행 파일이 공유 DLL에서 MFC를 사용하는 경우에도 함수는 항상 정적으로 연결됩니다. 공유 라이브러리 구현에서 함수는 MFCS42에서 찾을 수 있습니다. LIB 라이브러리(및 해당 변형).

이 함수를 성공적으로 사용하려면 다음을 수행합니다.

  • IMAGEHLP.DLL 파일은 경로에 있어야 합니다. 이 DLL이 없으면 함수에 오류 메시지가 표시됩니다. IMAGEHLP에서 제공하는 함수 집합에 대한 자세한 내용은 이미지 도움말 라이브러리를 참조하세요.

  • 스택에 프레임이 있는 모듈에는 디버깅 정보가 포함되어야 합니다. 디버깅 정보를 포함하지 않는 경우 함수는 여전히 스택 추적을 생성하지만 추적은 덜 자세히 설명합니다.

요구 사항

헤더: afx.h

AfxEnableMemoryLeakDump

AFX_DEBUG_STATE 소멸자에서 메모리 누수 덤프를 사용하거나 사용하지 않도록 설정합니다.

BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);

매개 변수

bDump
[in] TRUE는 메모리 누수 덤프가 사용됨을 나타냅니다. FALSE는 메모리 누수 덤프를 사용할 수 없음을 나타냅니다.

Return Value

이 플래그에 대한 이전 값입니다.

설명

애플리케이션이 MFC 라이브러리를 언로드하면 MFC 라이브러리는 메모리 누수를 확인합니다. 이 시점에서 메모리 누수는 Visual Studio의 디버그 창을 통해 사용자에게 보고됩니다.

애플리케이션이 MFC 라이브러리 전에 다른 라이브러리를 로드하는 경우, 해당 라이브러리의 일부 메모리 할당이 메모리 누수로 잘못 보고됩니다. 거짓 메모리 누수가 발생하면 MFC 라이브러리에서 이를 보고하므로 애플리케이션이 느리게 종료될 수 있습니다. 이 경우 메모리 누수 덤프를 사용하지 않으려면 AfxEnableMemoryLeakDump 를 사용합니다.

참고 항목

이 방법을 사용하여 메모리 누수 덤프를 끄는 경우, 애플리케이션에서 발생하는 유효한 메모리 누수의 보고서를 받지 못합니다. 메모리 누수 보고서에 거짓 메모리 누수가 포함되어 있다고 확신하는 경우에만 이 방법을 사용해야 합니다.

요구 사항

헤더: afx.h

AfxEnableMemoryTracking

진단 메모리 추적은 일반적으로 디버그 버전의 MFC에서 사용하도록 설정됩니다.

BOOL AfxEnableMemoryTracking(BOOL bTrack);

매개 변수

bTrack
이 값을 TRUE로 설정하면 메모리 추적이 켜집니다. FALSE는 해제합니다.

Return Value

추적 사용 플래그의 이전 설정입니다.

설명

이 함수를 사용하여 블록을 올바르게 할당하는 것으로 알고 있는 코드 섹션에서 추적을 사용하지 않도록 설정합니다.

자세한 내용은 AfxEnableMemoryTrackingMFC 애플리케이션 디버깅을 참조 하세요.

참고 항목

이 함수는 MFC의 디버그 버전에서만 작동합니다.

예시

BOOL CMyWinApp::InitInstance()
{
#ifdef _DEBUG
   // Disable tracking of memory for the scope of the InitInstance()
   AfxEnableMemoryTracking(FALSE);
#endif  // _DEBUG

   // ...

#ifdef _DEBUG
   // Re-enable tracking of memory
   AfxEnableMemoryTracking(TRUE);
#endif  // _DEBUG

   return TRUE;
}

요구 사항

헤더: afx.h

AfxIsMemoryBlock

메모리 주소를 테스트하여 진단 버전 new에서 할당한 현재 활성 메모리 블록을 나타내는지 확인합니다.

BOOL AfxIsMemoryBlock(
    const void* p,
    UINT nBytes,
    LONG* plRequestNumber = NULL);

매개 변수

p
테스트할 메모리 블록을 가리킵니다.

nBytes
메모리 블록의 길이(바이트)를 포함합니다.

plRequestNumber
long 메모리 블록의 할당 시퀀스 번호로 채워지는 정수를 가리키거나 현재 활성 메모리 블록을 나타내지 않는 경우 0을 가리킵니다.

Return Value

메모리 블록이 현재 할당되고 길이가 올바른 경우 0이 아닌 경우 그렇지 않으면 0입니다.

설명

또한 원래 할당된 크기에 대해 지정된 크기를 검사. 함수가 0이 아닌 값을 반환하면 할당 시퀀스 번호가 plRequestNumber반환됩니다. 이 숫자는 다른 new 모든 할당을 기준으로 블록이 할당된 순서를 나타냅니다.

예시

CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));

요구 사항

헤더: afx.h

AfxIsValidAddress

메모리 주소를 테스트하여 해당 주소가 프로그램의 메모리 공간 내에 완전히 포함되어 있는지 확인합니다.

BOOL AfxIsValidAddress(
    const void* lp,
    UINT nBytes,
    BOOL bReadWrite = TRUE);

매개 변수

lp
테스트할 메모리 주소를 가리킵니다.

nBytes
테스트할 메모리의 바이트 수를 포함합니다.

bReadWrite
메모리가 읽기 및 쓰기용인지(TRUE) 또는 읽기(FALSE)인지를 지정합니다.

Return Value

디버그 빌드에서 지정된 메모리 블록이 프로그램의 메모리 공간 내에 완전히 포함된 경우 0이 아닌 값입니다. 그렇지 않으면 0입니다.

디버그가 아닌 빌드에서는 lp가 NULL이 아니면 0이 아니고, 그렇지 않으면 0입니다.

설명

주소는 .에 의해 new할당된 블록으로 제한되지 않습니다.

예시

// Allocate a 5 character array, which should have a valid memory address.
char* arr = new char[5];

// Create a null pointer, which should be an invalid memory address.
char* null = (char*)0x0;

ASSERT(AfxIsValidAddress(arr, 5));
ASSERT(!AfxIsValidAddress(null, 5));

요구 사항

헤더: afx.h

AfxIsValidString

이 함수를 사용하여 문자열에 대한 포인터가 유효한지 여부를 확인합니다.

BOOL  AfxIsValidString(
    LPCSTR lpsz,
    int nLength = -1);

매개 변수

lpsz
테스트할 포인터입니다.

nLength
테스트할 문자열의 길이를 바이트 단위로 지정합니다. 값 -1은 문자열이 null로 종료됨을 나타냅니다.

Return Value

디버그 빌드에서 지정된 포인터가 지정된 크기의 문자열을 가리키는 경우 0이 아닌 값입니다. 그렇지 않으면 0입니다.

디버그가 아닌 빌드에서는 lpsz가 NULL이 아닌 경우 0이 아니고, 그렇지 않으면 0입니다.

예시

// Create a character string which should be valid.
char str[12] = "hello world";

// Create a null pointer, which should be an invalid string.
char* null = (char*)0x0;

ASSERT(AfxIsValidString(str, 12));
ASSERT(!AfxIsValidString(null, 5));

요구 사항

헤더: afx.h

AfxSetAllocHook

각 메모리 블록이 할당되기 전에 지정된 함수를 호출할 수 있도록 하는 후크를 설정합니다.

AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);

매개 변수

pfnAllocHook
호출할 함수의 이름을 지정합니다. 할당 함수의 프로토타입에 대한 비고를 참조하세요.

Return Value

할당을 허용하려는 경우 0이 아닌 경우 그렇지 않으면 0입니다.

설명

Microsoft Foundation 클래스 라이브러리 디버그 메모리 할당자는 사용자가 메모리 할당을 모니터링하고 할당이 허용되는지 여부를 제어할 수 있도록 사용자 정의 후크 함수를 호출할 수 있습니다. 할당 후크 함수는 다음과 같이 프로토타입화됩니다.

BOOL AFXAPI AllocHook( size_tnSize, BOOLbObject, LONGlRequestNumber);

nSize
제안된 메모리 할당의 크기입니다.

bObject
-derived 개체에 대한 CObject할당이면 TRUE이고, 그렇지 않으면 FALSE입니다.

lRequestNumber
메모리 할당의 시퀀스 번호입니다.

AFXAPI 호출 규칙은 호출 수신자가 스택에서 매개 변수를 제거해야 한다는 것을 의미합니다.

요구 사항

헤더: afx.h

AfxDoForAllClasses

애플리케이션 메모리 공간의 모든 직렬화 가능한 CObject파생 클래스에 대해 지정된 반복 함수를 호출합니다.

void
AFXAPI AfxDoForAllClasses(
    void (* pfn)(const CRuntimeClass* pClass, void* pContext),
    void* pContext);

매개 변수

pfn
각 클래스에 대해 호출할 반복 함수를 가리킵니다. 함수 인수는 개체에 대한 CRuntimeClass 포인터이며 호출자가 함수에 제공하는 추가 데이터에 대한 void 포인터입니다.

pContext
호출자가 반복 함수에 제공할 수 있는 선택적 데이터를 가리킵니다. 이 포인터는 NULL일 수 있습니다.

설명

serializable CObject-derived 클래스는 DECLARE_SERIAL 매크로를 사용하여 파생된 클래스입니다. pContext전달되는 AfxDoForAllClasses 포인터는 호출될 때마다 지정된 반복 함수에 전달됩니다.

참고 항목

이 함수는 MFC의 디버그 버전에서만 작동합니다.

예시

#ifdef _DEBUG
void DoForAllClasses(const CRuntimeClass* pClass, void* pContext)
{
   ASSERT(pContext != NULL);
   CString* pStr = (CString*)pContext;

   *pStr += pClass->m_lpszClassName;
   *pStr += _T("\n");
}
#endif

 

#ifdef _DEBUG
CString cStr;
AfxDoForAllClasses(DoForAllClasses, &cStr);
AfxMessageBox(cStr);
#endif

요구 사항

헤더: afx.h

AfxDoForAllObjects

로 할당된 개체에서 CObject 파생된 모든 개체에 대해 지정된 반복 함수를 new실행합니다.

void AfxDoForAllObjects(
    void (* pfn)(CObject* pObject, void* pContext),
    void* pContext);

매개 변수

pfn
각 개체에 대해 실행할 반복 함수를 가리킵니다. 함수 인수는 호출자가 함수에 CObject 제공하는 추가 데이터에 대한 포인터 및 void 포인터입니다.

pContext
호출자가 반복 함수에 제공할 수 있는 선택적 데이터를 가리킵니다. 이 포인터는 NULL일 수 있습니다.

설명

스택, 전역 또는 포함된 개체는 열거되지 않습니다. pContext전달된 AfxDoForAllObjects 포인터는 호출될 때마다 지정된 반복 함수에 전달됩니다.

참고 항목

이 함수는 MFC의 디버그 버전에서만 작동합니다.

예시

#ifdef _DEBUG
void DoForAllObjects(CObject* pObject, void* pContext)
{
   int* pnCount = (int*)pContext;

   pObject->AssertValid();
   if (pnCount != NULL)
      (*pnCount)++;
}
#endif // _DEBUG

 

#ifdef _DEBUG
//AfxDoForAllObjects will call the function DoForAllObjects 
//For each CObject-derived object that is allocated on the heap
int nCount = 0;
AfxDoForAllObjects(DoForAllObjects, &nCount);
TRACE("%d Objects Checked\n", nCount);
#endif

참고 항목

매크로 및 전역
CObject::Dump