Serviços de diagnóstico
A biblioteca Microsoft Foundation Class fornece muitos serviços de diagnóstico que facilitam a depuração de seus programas. Esses serviços de diagnóstico incluem macros e funções globais que permitem acompanhar as alocações de memória do programa, despejar o conteúdo dos objetos durante o tempo de execução e imprimir mensagens de depuração durante o tempo de execução. As macros e as funções globais para serviços de diagnóstico são agrupadas nas seguintes categorias:
Macros de diagnóstico geral
Variáveis e funções de diagnóstico gerais
Funções de diagnóstico de objeto
Essas macros e funções estão disponíveis para todas as classes derivadas de CObject
nas versões de Depuração e de Lançamento do MFC. No entanto, todos, exceto DEBUG_NEW e VERIFY, não fazem nada na versão de Lançamento.
Na biblioteca de Depuração, todos os blocos de memória alocados estão entre colchetes com uma série de "bytes de proteção". Se esses bytes forem afetados por uma gravação de memória errática, as rotinas de diagnóstico poderão relatar um problema. Se você incluir a linha:
#define new DEBUG_NEW
no seu arquivo de implementação, todas as chamadas para new
armazenarão o nome do arquivo e o número de linha em que a alocação de memória ocorreu. A função CMemoryState::DumpAllObjectsSince exibirá essas informações extras, permitindo identificar vazamentos de memória. Confira também a classe CDumpContext para obter informações adicionais sobre a saída de diagnóstico.
Além disso, a biblioteca de runtime C também dá suporte a um conjunto de funções de diagnóstico que você pode usar para depurar seus aplicativos. Para obter mais informações, confira Rotinas de depuração na Referência da biblioteca de runtime.
Macros de diagnóstico geral do MFC
Nome | Descrição |
---|---|
ASSERT | Imprime uma mensagem e anula o programa se a expressão especificada for avaliada como FALSE na versão de depuração da biblioteca. |
ASSERT_KINDOF | Testa se um objeto é um objeto da classe especificada ou de uma classe derivada da classe especificada. |
ASSERT_VALID | Testa a validade interna de um objeto chamando a respectiva função membro AssertValid ; normalmente substituído de CObject . |
DEBUG_NEW | Fornece um nome de arquivo e um número de linha para todas as alocações de objeto no modo de depuração para ajudar a encontrar vazamentos de memória. |
DEBUG_ONLY | Semelhante a ASSERT, mas não testa o valor da expressão; útil para código que deve ser executado somente no modo de depuração. |
ENSURE e ENSURE_VALID | Use para validar a exatidão dos dados. |
THIS_FILE | Expande para o nome do arquivo que está sendo compilado. |
TRACE | Fornece uma funcionalidade semelhante a printf na versão de depuração da biblioteca. |
VERIFY | Semelhante a ASSERT, mas avalia a expressão na versão de lançamento da biblioteca, bem como na versão de depuração. |
Funções e variáveis de diagnóstico gerais do MFC
Nome | Descrição |
---|---|
afxDump | Variável global que envia informações de CDumpContext para a janela de saída do depurador ou para o terminal de depuração. |
afxMemDF | Variável global que controla o comportamento do alocador de memória de depuração. |
AfxCheckError | Variável global usada para testar o SCODE passado para ver se é um erro e, se for o caso, gerar o erro apropriado. |
AfxCheckMemory | Verifica a integridade de toda a memória alocada no momento. |
AfxDebugBreak | Causa uma interrupção na execução. |
AfxDump | Se chamado no depurador, despeja o estado de um objeto durante a depuração. |
AfxDump | Função interna que despeja o estado de um objeto durante a depuração. |
AfxDumpStack | Gere uma imagem da pilha atual. Essa função está sempre vinculada estaticamente. |
AfxEnableMemoryLeakDump | Habilita o despejo de perda de memória. |
AfxEnableMemoryTracking | Ativa e desativa o acompanhamento de memória. |
AfxIsMemoryBlock | Verifica se um bloco de memória foi alocado corretamente. |
AfxIsValidAddress | Verifica se um intervalo de endereços de memória está dentro dos limites do programa. |
AfxIsValidString | Determina se um ponteiro para uma cadeia de caracteres é válido. |
AfxSetAllocHook | Habilita a chamada de uma função em cada alocação de memória. |
Funções de diagnóstico de objeto MFC
Nome | Descrição |
---|---|
AfxDoForAllClasses | Executa uma função especificada em todas as classes derivadas de CObject que dão suporte à verificação de tipo de tempo de execução. |
AfxDoForAllObjects | Executa uma função especificada em todos os objetos derivados de CObject que foram alocados com new . |
Macros de compilação do MFC
Nome | Descrição |
---|---|
_AFX_SECURE_NO_WARNINGS | Suprime avisos do compilador para o uso de funções do MFC preteridas. |
_AFX_SECURE_NO_WARNINGS
Suprime avisos do compilador para o uso de funções do MFC preteridas.
Sintaxe
_AFX_SECURE_NO_WARNINGS
Exemplo
Esse exemplo de código causa um aviso do compilador se _AFX_SECURE_NO_WARNINGS
não estiver definido.
// 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
Chame essa função para causar uma interrupção (no local da chamada para AfxDebugBreak
) na execução da versão de depuração do aplicativo MFC.
Sintaxe
void AfxDebugBreak( );
Comentários
AfxDebugBreak
não tem efeito nas versões de lançamento de um aplicativo MFC e deve ser removido. Essa função só deve ser usada em aplicativos MFC. Use a versão DebugBreak
da API do Win32 para causar uma interrupção em aplicativos não MFC.
Requisitos
Cabeçalho: afxver_.h
ASSERT
Avalia o argumento dele.
ASSERT(booleanExpression)
Parâmetros
booleanExpression
Especifica uma expressão (incluindo valores de ponteiro) que é avaliada como diferente de zero ou 0.
Comentários
Se o resultado for 0, a macro imprimirá uma mensagem de diagnóstico e anulará o programa. Se a condição for diferente de zero, não fará nada.
A mensagem de diagnóstico tem o formato
assertion failed in file <name> in line <num>
em que name é o nome do arquivo de origem e num é o número de linha da declaração que falhou no arquivo de origem.
Na versão de lançamento do MFC, ASSERT não avalia a expressão e, portanto, não interromperá o programa. Se a expressão precisar ser avaliada independentemente do ambiente, use a macro VERIFY no lugar de ASSERT.
Observação
Essa função está disponível somente na versão de depuração do MFC.
Exemplo
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*.
Requisitos
Cabeçalho: afx.h
ASSERT_KINDOF
Essa macro afirma que o objeto apontado é um objeto da classe especificada ou é um objeto de uma classe derivada da classe especificada.
ASSERT_KINDOF(classname, pobject)
Parâmetros
classname
O nome de uma classe derivada de CObject
.
pobject
Um ponteiro para um objeto de classe.
Comentários
O parâmetro pobject deve ser um ponteiro para um objeto e pode ser const
. O objeto apontado e a classe precisam dar suporte a informações da classe runtime CObject
. Como exemplo, para garantir que pDocument
seja um ponteiro para um objeto da classe CMyDoc
ou qualquer uma das derivadas dela, você pode codificar:
ASSERT_KINDOF(CMyDoc, pDocument);
Usar a macro ASSERT_KINDOF
é exatamente o mesmo que codificar o seguinte:
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
Essa função funciona apenas para classes declaradas com a macro [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic ou macro DECLARE_SERIAL.
Observação
Essa função está disponível somente na versão de depuração do MFC.
Requisitos
Cabeçalho: afx.h
ASSERT_VALID
Use para testar suas suposições sobre a validade do estado interno de um objeto.
ASSERT_VALID(pObject)
Parâmetros
pObject
Especifica um objeto de uma classe derivada de CObject
que tem uma versão de substituição da função membro AssertValid
.
Comentários
ASSERT_VALID chama a função membro AssertValid
do objeto passado como argumento dela.
Na versão de lançamento do MFC, ASSERT_VALID não faz nada. Na versão de depuração, ela valida o ponteiro, verifica se a o valor retornado é NULL e chama as funções membro AssertValid
do próprio objeto. Se algum desses testes falhar, uma mensagem de alerta será exibida da mesma maneira que ASSERT.
Observação
Essa função está disponível somente na versão de depuração do MFC.
Para mais informações e exemplos, confira Como depurar aplicativos MFC.
Exemplo
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
Requisitos
Cabeçalho: afx.h
DEBUG_NEW
Auxilia na detecção de vazamentos de memória.
#define new DEBUG_NEW
Comentários
Você pode usar DEBUG_NEW em todos os lugares do programa que normalmente usaria o operador new
para alocar o armazenamento de heap.
No modo de depuração (quando o símbolo _DEBUG é definido), DEBUG_NEW mantém o controle do nome do arquivo e do número de linha para cada objeto que ele aloca. Em seguida, quando você usa a função membro CMemoryState::DumpAllObjectsSince, cada objeto alocado com DEBUG_NEW é mostrado com o nome do arquivo e o número de linha em que ele foi alocado.
Para usar DEBUG_NEW, insira a seguinte diretiva em seus arquivos de origem:
#define new DEBUG_NEW
Depois de inserir essa diretiva, o pré-processador inserirá DEBUG_NEW onde quer que você use new
, e o MFC fará o restante. Quando você compila uma versão de lançamento do programa, DEBUG_NEW resolve para uma operação simples new
e as informações de nome de arquivo e número de linha não são geradas.
Observação
Em versões anteriores do MFC (4.1 e anteriores), você precisava colocar a instrução #define
depois de todas as instruções que chamavam as macros IMPLEMENT_DYNCREATE ou IMPLEMENT_SERIAL. Isso não é mais necessário.
Requisitos
Cabeçalho: afx.h
DEBUG_ONLY
No modo de depuração (quando o símbolo _DEBUG é definido), DEBUG_ONLY avalia o próprio argumento.
DEBUG_ONLY(expression)
Comentários
Em um build de versão, DEBUG_ONLY não avalia o próprio argumento. Isso é útil quando você tem um código que deve ser executado somente em builds de depuração.
A macro DEBUG_ONLY é equivalente à expressão circundante com #ifdef _DEBUG
e #endif
.
Exemplo
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');
}
Requisitos
Cabeçalho: afx.h
ENSURE e ENSURE_VALID
Use para validar a exatidão dos dados.
Sintaxe
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
Parâmetros
booleanExpression
Especifica uma expressão booliana a ser testada.
Comentários
A finalidade dessas macros é aprimorar a validação de parâmetros. As macros impedem o processamento adicional de parâmetros incorretos em seu código. Ao contrário das macros ASSERT, as macros ENSURE geram uma exceção, além de gerar uma declaração.
As macros se comportam de duas maneiras, de acordo com a configuração do projeto. As macros chamam ASSERT e geram uma exceção se a declaração falha. Assim, em configurações de depuração (ou seja, onde _DEBUG está definido) as macros produzem uma declaração e uma exceção enquanto nas configurações de versão, as macros produzem apenas a exceção (ASSERT não avalia a expressão em configurações de lançamento).
A macro ENSURE_ARG atua como a macro ENSURE.
ENSURE_VALID chama a macro ASSERT_VALID (que tem um efeito somente em builds de depuração). Além disso, ENSURE_VALID gerará uma exceção se o ponteiro for NULL. O teste NULL é executado nas configurações de depuração e lançamento.
Se algum desses testes falhar, uma mensagem de alerta será exibida da mesma maneira que ASSERT. A macro gera uma exceção de argumento inválida, se necessário.
Requisitos
Cabeçalho: afx.h
THIS_FILE
Expande para o nome do arquivo que está sendo compilado.
Sintaxe
THIS_FILE
Comentários
As informações são usadas pelas macros ASSERT e VERIFY. O Assistente de Aplicativo e os assistentes de código colocam a macro nos arquivos de código-fonte que eles criam.
Exemplo
#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.
Requisitos
Cabeçalho: afx.h
TRACE
Envia a cadeia de caracteres especificada para o depurador do aplicativo atual.
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
Comentários
Confira ATLTRACE2 para obter uma descrição de TRACE. TRACE e ATLTRACE2 têm o mesmo comportamento.
Na versão de depuração do MFC, essa macro envia a cadeia de caracteres especificada para o depurador do aplicativo atual. Em um build de lançamento, a compilação dessa macro resulta em nada (nenhum código é gerado).
Para obter mais informações, confira Como depurar aplicativos MFC.
Requisitos
Cabeçalho: afx.h
VERIFY
Na versão de depuração do MFC, avalia o próprio argumento.
VERIFY(booleanExpression)
Parâmetros
booleanExpression
Especifica uma expressão (incluindo valores de ponteiro) que é avaliada como diferente de zero ou 0.
Comentários
Se o resultado for 0, a macro imprimirá uma mensagem de diagnóstico e interromperá o programa. Se a condição for diferente de zero, não fará nada.
A mensagem de diagnóstico tem o formato
assertion failed in file <name> in line <num>
em que name é o nome do arquivo de origem e num é o número de linha da declaração que falhou no arquivo de origem.
Na versão de lançamento do MFC, VERIFY avalia a expressão, mas não imprime nem interrompe o programa. Por exemplo, se a expressão for uma chamada de função, a chamada será feita.
Exemplo
// 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);
Requisitos
Cabeçalho: afx.h
afxDump (CDumpContext no MFC)
Fornece a funcionalidade básica de despejo de objeto em seu aplicativo.
CDumpContext afxDump;
Comentários
afxDump
é um objeto CDumpContext predefinido que permite enviar informações de CDumpContext
para a janela de saída do depurador ou para um terminal de depuração. Normalmente, você fornece afxDump
como um parâmetro para CObject::Dump
.
Em Windows NT e todas as versões do Windows, a saída afxDump
é enviada para a janela Depuração de Saída do Visual C++ quando você depura seu aplicativo.
Essa variável é definida apenas na versão de depuração do MFC. Para obter mais informações sobre afxDump
, confira Como depurar aplicativos MFC.
Exemplo
// 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
Requisitos
Cabeçalho: afx.h
AfxDump (Interno)
Função interna que o MFC usa para despejar o estado de um objeto durante a depuração.
Sintaxe
void AfxDump(const CObject* pOb);
Parâmetros
pOb
Um ponteiro para um objeto de uma classe derivada de CObject
.
Comentários
AfxDump
chama a função membro Dump
de um objeto e envia as informações para o local especificado pela variável afxDump
. AfxDump
está disponível somente na versão de depuração do MFC.
O código do programa não deve chamar AfxDump
, mas deve chamar a função membro Dump
do objeto apropriado.
Requisitos
Cabeçalho: afx.h
afxMemDF
Essa variável pode ser acessada por meio de um depurador ou programa e permite ajustar o diagnóstico de alocação.
int afxMemDF;
Comentários
afxMemDF
pode ter os seguintes valores, conforme especificado pela enumeração afxMemDF
:
allocMemDF
Desativa o alocador de depuração (configuração padrão na biblioteca de depuração).delayFreeMemDF
Atrasa a liberação de memória. Embora seu programa libere um bloco de memória, o alocador não retorna essa memória para o sistema operacional subjacente. Isso colocará o estresse máximo de memória em seu programa.checkAlwaysMemDF
chamaAfxCheckMemory
toda vez que a memória é alocada ou liberada. Isso reduzirá significativamente a velocidade das alocações e desalocações de memória.
Exemplo
afxMemDF = allocMemDF | checkAlwaysMemDF;
Requisitos
Cabeçalho: afx.h
AfxCheckError
Essa função testa o SCODE passado para ver se ele é um erro.
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
Comentários
Se for um erro, a função gerará uma exceção. Se o SCODE passado for E_OUTOFMEMORY, a função gerará uma CMemoryException chamando AfxThrowMemoryException. Caso contrário, a função gerará uma COleException chamando AfxThrowOleException.
Essa função pode ser usada para verificar os valores retornados de chamadas para funções OLE em seu aplicativo. Ao testar o valor retornado com essa função em seu aplicativo, você pode reagir corretamente às condições de erro com uma quantidade mínima de código.
Observação
Essa função tem o mesmo efeito em builds de depuração e não depuração.
Exemplo
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
Requisitos
Cabeçalho: afx.h
AfxCheckMemory
Essa função valida o pool de memória livre e imprime mensagens de erro conforme necessário.
BOOL AfxCheckMemory();
Valor de retorno
Diferente de zero se não houver erros de memória; caso contrário, 0.
Comentários
Se a função não detectar corrupção de memória, ela não imprimirá nada.
Todos os blocos de memória atualmente alocados no heap são verificados, incluindo aqueles alocados por new
, mas não aqueles alocados por chamadas diretas para alocadores de memória subjacentes, como a função malloc ou a função GlobalAlloc
do Windows. Se algum bloco estiver corrompido, uma mensagem será impressa na saída do depurador.
Se você incluir a linha
#define new DEBUG_NEW
em um módulo de programa, as chamadas subsequentes para AfxCheckMemory
mostrarão o nome do arquivo e o número de linha em que a memória foi alocada.
Observação
Se o módulo contiver uma ou mais implementações de classes serializáveis, você precisará colocar a linha #define
após a última chamada de macro IMPLEMENT_SERIAL.
Essa função funciona apenas na versão de depuração do MFC.
Exemplo
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();
Requisitos
Cabeçalho: afx.h
AfxDump (MFC)
Chame essa função enquanto estiver no depurador para despejar o estado de um objeto durante a depuração.
void AfxDump(const CObject* pOb);
Parâmetros
pOb
Um ponteiro para um objeto de uma classe derivada de CObject
.
Comentários
AfxDump
chama a função membro Dump
de um objeto e envia as informações para o local especificado pela variável afxDump
. AfxDump
está disponível somente na versão de depuração do MFC.
O código do programa não deve chamar AfxDump
, mas deve chamar a função membro Dump
do objeto apropriado.
Requisitos
Cabeçalho: afx.h
AfxDumpStack
Essa função global pode ser usada para gerar uma imagem da pilha atual.
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
Parâmetros
dwTarget
Indica o destino da saída de despejo. Os valores possíveis, que podem ser combinados usando o operador or bit a bit (|
), são os seguintes:
AFX_STACK_DUMP_TARGET_TRACE Envia a saída por meio da macro TRACE. A macro TRACE gera saída somente em builds de depuração; ele não gera nenhuma saída em builds de lançamento. Além disso, TRACE pode ser redirecionado para outros destinos além do depurador.
AFX_STACK_DUMP_TARGET_DEFAULT Envia a saída de despejo para o destino padrão. Para um build de depuração, a saída vai para a macro TRACE. Em um build de lançamento, a saída vai para a Área de Transferência.
AFX_STACK_DUMP_TARGET_CLIPBOARD Envia apenas a saída para a área de transferência. Os dados são colocados na área de transferência como texto sem formatação usando o formato CF_TEXT de área de transferência.
AFX_STACK_DUMP_TARGET_BOTH Envia a saída para a Área de Transferência e para a macro TRACE simultaneamente.
AFX_STACK_DUMP_TARGET_ODS Envia a saída diretamente para o depurador por meio da função
OutputDebugString()
do Win32. Essa opção gerará a saída do depurador em builds de depuração e versão quando um depurador for anexado ao processo. AFX_STACK_DUMP_TARGET_ODS sempre atinge o depurador (se ele estiver anexado) e não pode ser redirecionado.
Comentários
O exemplo a seguir reflete apenas uma linha da saída gerada chamando AfxDumpStack
de um manipulador de botões em um aplicativo de diálogo do MFC:
=== 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 ===
Cada linha na saída acima indica o endereço da última chamada de função, o nome completo do caminho do módulo que contém a chamada de função e o protótipo de função chamado. Se a chamada de função na pilha não ocorrer no endereço exato da função, um deslocamento de bytes será mostrado.
Por exemplo, a tabela a seguir descreve a primeira linha da saída acima:
Saída | Descrição |
---|---|
00427D55: |
O endereço de retorno da última chamada de função. |
DUMP2\DEBUG\DUMP2.EXE! |
O nome do módulo que contém a linha da função. |
void AfxDumpStack(unsigned long) |
O protótipo de função chamado. |
+ 181 bytes |
O deslocamento em bytes do endereço do protótipo da função (neste caso, void AfxDumpStack(unsigned long) ) para o endereço de retorno (neste caso, 00427D55 ). |
AfxDumpStack
está disponível em versões de depuração e não depuração das bibliotecas do MFC; no entanto, a função é sempre vinculada estaticamente, mesmo quando o arquivo executável usa o MFC em uma DLL compartilhada. Em implementações de biblioteca compartilhada, a função é encontrada na biblioteca MFCS42.LIB (e nas variantes dela).
Para usar essa função com êxito:
O arquivo IMAGEHLP.DLL precisa estar no caminho. Se você não tiver essa DLL, a função exibirá uma mensagem de erro. Consulte a Biblioteca de Ajuda à Imagem para obter informações sobre o conjunto de funções fornecido por IMAGEHLP.
Os módulos que têm quadros na pilha precisam incluir informações de depuração. Se eles não contiverem informações de depuração, a função ainda gerará um rastreamento de pilha, mas o rastreamento será menos detalhado.
Requisitos
Cabeçalho: afx.h
AfxEnableMemoryLeakDump
Habilita e desabilita o despejo de memória no destruidor AFX_DEBUG_STATE.
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
Parâmetros
bDump
[in] TRUE indica que o despejo de memória está habilitado; FALSE indica que o despejo de memória está desabilitado.
Valor de retorno
O valor anterior desse sinalizador.
Comentários
Quando um aplicativo descarrega a biblioteca do MFC, a biblioteca do MFC verifica se há vazamentos de memória. Neste ponto, todos os vazamentos de memória são relatados ao usuário por meio da janela Depuração do Visual Studio.
Se o aplicativo carregar outra biblioteca antes da biblioteca do MFC, algumas alocações de memória nessa biblioteca serão relatadas incorretamente como vazamentos de memória. Vazamentos de memória falsos podem fazer com que seu aplicativo feche lentamente conforme a biblioteca do MFC os relata. Nesse caso, use AfxEnableMemoryLeakDump
para desabilitar o despejo de memória.
Observação
Se você usar esse método para desativar o despejo de memória, não receberá relatórios de vazamentos de memória válidos em seu aplicativo. Você só deve usar esse método se estiver confiante de que o relatório de vazamento de memória contém vazamentos de memória falsos.
Requisitos
Cabeçalho: afx.h
AfxEnableMemoryTracking
O rastreamento de memória de diagnóstico normalmente está habilitado na versão de depuração do MFC.
BOOL AfxEnableMemoryTracking(BOOL bTrack);
Parâmetros
bTrack
Definir esse valor como TRUE ativa o rastreamento de memória; FALSE o desativa.
Valor de retorno
A configuração anterior do sinalizador de habilitação de rastreamento.
Comentários
Use essa função para desabilitar o acompanhamento em seções do código que você sabe que estão alocando blocos corretamente.
Para obter mais informações sobre AfxEnableMemoryTracking
, confira Como depurar aplicativos MFC.
Observação
Essa função funciona apenas na versão de depuração do MFC.
Exemplo
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;
}
Requisitos
Cabeçalho: afx.h
AfxIsMemoryBlock
Testa um endereço de memória para garantir que ele represente um bloco de memória ativo atualmente alocado pela versão de diagnóstico de new
.
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
Parâmetros
p
Aponta para o bloco de memória a ser testado.
nBytes
Contém o comprimento do bloco de memória em bytes.
plRequestNumber
Aponta para um inteiro long
que será preenchido com o número de sequência de alocação do bloco de memória ou zero se ele não representar um bloco de memória ativo no momento.
Valor de retorno
Diferente de zero se o bloco de memória estiver alocado no momento e o comprimento estiver correto; caso contrário, 0.
Comentários
Ele também verifica o tamanho especificado em relação ao tamanho alocado original. Se a função retornar um valor diferente de zero, o número da sequência de alocação será retornado em plRequestNumber. Esse número representa a ordem na qual o bloco foi alocado em relação a todas as outras alocações de new
.
Exemplo
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
Requisitos
Cabeçalho: afx.h
AfxIsValidAddress
Testa qualquer endereço de memória para garantir que ele esteja totalmente contido no espaço de memória do programa.
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
Parâmetros
LP
Aponta para o endereço de memória a ser testado.
nBytes
Contém o número de bytes de memória a serem testados.
bReadWrite
Especifica se a memória é para leitura e gravação (TRUE) ou apenas leitura (FALSE).
Valor de retorno
Em builds de depuração, diferente de zero se o bloco de memória especificado estiver totalmente contido no espaço de memória do programa; caso contrário, 0.
Em builds não de depuração, retornará um valor diferente de zero se lp não for NULL; caso contrário, 0.
Comentários
O endereço não está restrito a blocos alocados por new
.
Exemplo
// 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));
Requisitos
Cabeçalho: afx.h
AfxIsValidString
Use essa função para determinar se um ponteiro para uma cadeia de caracteres é válido.
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
Parâmetros
lpsz
O ponteiro a ser testado.
nLength
Especifica o comprimento da cadeia de caracteres a ser testada, em bytes. Um valor de -1 indica que a cadeia de caracteres será terminada em nulo.
Valor de retorno
Em builds de depuração, retornará um valor diferente de zero se o ponteiro especificado apontar para uma cadeia de caracteres do tamanho especificado; caso contrário, 0.
Em builds não de depuração, retornará um valor diferente de zero se lpsz não for NULL; caso contrário, 0.
Exemplo
// 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));
Requisitos
Cabeçalho: afx.h
AfxSetAllocHook
Define um gancho que permite chamar a função especificada antes que cada bloco de memória seja alocado.
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
Parâmetros
pfnAllocHook
Especifica o nome da função a ser chamada. Consulte os Comentários do protótipo de uma função de alocação.
Valor de retorno
Diferente de zero se você quiser permitir a alocação; caso contrário, 0.
Comentários
O alocador de memória de depuração da biblioteca Microsoft Foundation Class pode chamar uma função de gancho definida pelo usuário para permitir que o usuário monitore uma alocação de memória e controle se a alocação é permitida. Os protótipos das funções de gancho de alocação são criados da seguinte maneira:
BOOL AFXAPI AllocHook( size_t nSize
, BOOLbObject
, LONG ); lRequestNumber
nSize
O tamanho da alocação de memória proposta.
bObject
TRUE se a alocação for para um objeto derivado de CObject
; caso contrário, FALSE.
lRequestNumber
O número de sequência da alocação de memória.
Observe que a convenção de chamada AFXAPI implica que o computador chamado precisa remover os parâmetros da pilha.
Requisitos
Cabeçalho: afx.h
AfxDoForAllClasses
Chama a função de iteração especificada para todas as classes serializáveis derivadas de CObject
no espaço de memória do aplicativo.
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
Parâmetros
pfn
Aponta para uma função de iteração a ser chamada para cada classe. Os argumentos de função são um ponteiro para um objeto CRuntimeClass
e um ponteiro vazio para dados extras que o chamador fornece para a função.
pContext
Aponta para dados opcionais que o chamador pode fornecer para a função de iteração. Este ponteiro pode ser NULO.
Comentários
Classes serializáveis derivadas de CObject
são classes derivadas usando a macro DECLARE_SERIAL. O ponteiro que é passado para AfxDoForAllClasses
em pContext é passado para a função de iteração especificada cada vez que ela é chamada.
Observação
Essa função funciona apenas na versão de depuração do MFC.
Exemplo
#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
Requisitos
Cabeçalho: afx.h
AfxDoForAllObjects
Executa a função de iteração especificada para todos os objetos derivados de CObject
que foram alocados com new
.
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
Parâmetros
pfn
Aponta para uma função de iteração a ser executada para cada objeto. Os argumentos de função são um ponteiro para um CObject
e um ponteiro vazio para dados extras que o chamador fornece para a função.
pContext
Aponta para dados opcionais que o chamador pode fornecer para a função de iteração. Este ponteiro pode ser NULO.
Comentários
Objetos de pilha, globais ou inseridos não são enumerados. O ponteiro passado para AfxDoForAllObjects
em pContext é passado para a função de iteração especificada cada vez que ela é chamada.
Observação
Essa função funciona apenas na versão de depuração do MFC.
Exemplo
#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