Rastreamento de solicitações de alocação de Heap

This topic applies to:

Edition

Visual Basic

C#

F#

C++

Web Developer

Express

O tópico não é aplicável O tópico não é aplicável O tópico não é aplicável

Native only

O tópico não é aplicável

Pro, Premium e Ultimate

O tópico não é aplicável O tópico não é aplicável O tópico não é aplicável

Native only

O tópico não é aplicável

Embora identificando o número origem de linha e o nome de arquivo em que o executa um assert ou o relatório de macro geralmente é muito útil para localizar a causa do problema, o mesmo não é mais provável de serem verdadeiras das funções de alocação de heap. Enquanto as macros podem ser inseridas em muitos pontos apropriados na árvore de lógica do aplicativo, uma alocação freqüentemente é incluída em uma rotina especial que é chamada a partir de muitos locais diferentes em vários momentos diferentes. A pergunta é geralmente não qual linha de código feita uma alocação incorreta, mas em vez disso, o qual uma das milhares de alocações feitas por essa linha de código foi incorreto e por quê.

_CrtBreakAlloc e números exclusivos de solicitação de alocação

A maneira mais simples para identificar a chamada de alocação de heap específicos que ficou ruim é aproveitar o número de solicitação de alocação exclusivo associado a cada bloco na pilha de depuração. Quando as informações sobre um bloco são relatadas por uma das funções de despejo, esse número de solicitação de alocação é entre chaves (por exemplo, "{36}").

Quando você souber o número de solicitação de alocação de um bloco reservado incorretamente, você pode passar esse número para _CrtSetBreakAlloc para criar um ponto de interrupção. A execução interromperá antes de alocar o bloco e você pode refazer o caminho para determinar qual rotina era responsável pela chamada incorreta. Para evitar a recompilação, você pode realizar a mesma coisa no depurador definindo _crtBreakAlloc para o número de solicitação de alocação que você está interessado.

Criação de versões de depuração de suas rotinas de alocação

Uma abordagem um pouco mais complicada é criar versões de depuração de suas próprias rotinas de alocação, comparáveis da _dbg versões da funções de alocação de heap. Depois poderá passar o arquivo de origem e de linha por meio de argumentos de número para as rotinas de alocação de heap subjacente, e você poderá imediatamente ver onde foi originada de uma alocação incorreta.

Por exemplo, suponha que seu aplicativo contém uma rotina comumente usada semelhante à seguinte:

int addNewRecord(struct RecStruct * prevRecord,
                 int recType, int recAccess)
{
    // ...code omitted through actual allocation... 
    if ((newRec = malloc(recSize)) == NULL)
    // ... rest of routine omitted too ... 
}

Em um arquivo de cabeçalho, você poderia adicionar código como, por exemplo, o seguinte:

#ifdef _DEBUG
#define  addNewRecord(p, t, a) \
            addNewRecord(p, t, a, __FILE__, __LINE__)
#endif

Em seguida, você poderia alterar a alocação em sua rotina de criação de registros da seguinte maneira:

int addNewRecord(struct RecStruct *prevRecord,
                int recType, int recAccess
#ifdef _DEBUG
               , const char *srcFile, int srcLine
#endif
    )
{
    /* ... code omitted through actual allocation ... */
    if ((newRec = _malloc_dbg(recSize, _NORMAL_BLOCK,
            srcFile, scrLine)) == NULL)
    /* ... rest of routine omitted too ... */
}

Agora o arquivo de origem nome e a linha número onde addNewRecord foi chamado serão armazenadas em cada bloco resultante alocado na pilha de depuração e será reportado quando desse bloco é examinado.

Consulte também

Outros recursos

A pilha de depuração do CRT