Como posso obter o tamanho de um bloco de memória alocada usando malloc ()? [duplicado]

StackOverflow https://stackoverflow.com/questions/1208644

Pergunta

Duplicatas possíveis:
Como posso obter o tamanho de uma matriz de um ponteiro em C?
Existe qualquer maneira para determinar o tamanho de matriz um C ++ programaticamente? E se não, por quê?

Eu obter um ponteiro para um bloco de memória alocada a partir de uma função de estilo C. Agora, seria muito interessante para fins de depuração para saber como grande bloco de memória alocada que esse ponteiro aponta é.

Existe algo mais elegante do que provocar uma exceção por cegamente atropelando seus limites?

Agradecemos antecipadamente, Andreas

EDIT:

Eu uso VC ++ 2005 no Windows, e GCC 4.3 no Linux

EDIT2:

Eu tenho _msize sob VC ++ 2005 Infelizmente isso resulta em uma exceção no modo de depuração ....

EDIT3:

Bem. Eu tentei a maneira que eu descrevi acima, com a exceção, e ele funciona. Pelo menos, enquanto eu estou depuração e garantir que imediatamente após a chamada para as saídas de biblioteca Eu corro ao longo dos limites de buffer. Funciona como um encanto.

Ele só não é elegante e de nenhuma forma utilizável no código de produção.

Foi útil?

Solução

Não é padrão, mas se a sua biblioteca tem uma função msize() que lhe dará o tamanho.

Uma solução comum é envolvê malloc com sua própria função que registra cada solicitação junto com o tamanho e intervalo de memória resultante, na compilação de lançamento pode voltar para a malloc 'real'.

Outras dicas

Se você não se importa violência desprezível por causa de depuração, você pode #define macros para ligar as chamadas para malloc e gratuitos e almofada os primeiros 4 bytes com o tamanho.

Para a melodia de

void *malloc_hook(size_t size) {
    size += sizeof (size_t);
    void *ptr = malloc(size);
    *(size_t *) ptr = size;
    return ((size_t *) ptr) + 1;
}

void free_hook (void *ptr) {
    ptr = (void *) (((size_t *) ptr) - 1);
    free(ptr);
}

size_t report_size(ptr) {
    return * (((size_t *) ptr) - 1);
}

então

#define malloc(x) malloc_hook(x)

e assim por diante

A biblioteca de tempo de execução C não fornece tal função. Além disso, deliberadamente provocar uma exceção não irá dizer-lhe como é grande o bloco é qualquer um.

Normalmente, a forma como este problema é resolvido em C é manter uma variável separada, que mantém o controle do tamanho do bloco alocado. Claro, isso às vezes é inconveniente, mas há geralmente nenhuma outra maneira de saber.

A sua biblioteca C runtime pode fornecer algumas funções pilha de depuração que pode consultar blocos alocados (afinal, necessidades free() saber quão grande é o bloco é), mas qualquer um esse tipo de coisa será não portável .

Com gcc eo GNU linker, você pode facilmente quebrar malloc

#include <stdlib.h>
#include <stdio.h>


void* __real_malloc(size_t sz);
void* __wrap_malloc(size_t sz)
{
    void *ptr;

    ptr = __real_malloc(sz);
    fprintf(stderr, "malloc of size %d yields pointer %p\n", sz, ptr);

    /* if you wish to save the pointer and the size to a data structure, 
       then remember to add wrap code for calloc, realloc and free */

    return ptr;
}

int main()
{
    char *x;
    x = malloc(103);

    return 0;
}

e compilação com

gcc a.c -o a -Wall -Werror -Wl,--wrap=malloc

(Claro, isso também irá trabalhar com c ++ código compilado com g ++, e com o novo operador (nome através da sua mutilado), se desejar.)

Com efeito, a biblioteca estaticamente / carregado dinamicamente também usará o seu __wrap_malloc.

Não, e você não pode confiar em uma exceção quando ultrapassagem de seus limites, a menos que seja na documentação do seu implementação. É parte das coisas que você realmente não precisa de saber sobre a programas de gravação. Dig em documentação ou código fonte de seu compilador se você realmente quer saber.

Não há nenhuma função padrão C para fazer isso. Dependendo da sua plataforma, pode haver um método não-portátil - o que OS e uma biblioteca C que você está usando

Note que provoca uma exceção não é confiável -. Pode haver outras atribuições imediatamente após o pedaço que você tem, e assim você não pode obter uma exceção até muito tempo depois de exceder os limites de seu pedaço de corrente

verificadores de memória como do Valgrind memcheck e TCMalloc do Google (o verificador de pilha parte) faixa de manter esse tipo de coisa.

Você pode usar TCMalloc para despejar um perfil pilha que mostra onde as coisas ficaram alocados, ou você pode apenas tê-lo certifique-se de sua pilha é a mesma em dois pontos a execução do programa usando SameHeap () .

solução parcial:. No Windows, você pode usar o PageHeap para pegar um acesso à memória fora do bloco alocado

PageHeap é um gerenciador de memória alternativo presente no kernel do Windows (nas variedades NT mas ninguém deve estar usando qualquer outra versão hoje em dia). Leva cada alocação em um processo e retorna um bloco de memória que tem seu fim alinhado com o final de uma página de memória, então faz a seguinte página inacessível (sem leitura, sem acesso de gravação). Se as tentativas de programa para ler ou escrever além do fim do bloco, você poderá obter uma violação de acesso pode apanhar com o seu depurador favorito.

Como obtê-lo: Faça o download e instale o pacote de ferramentas de depuração para Windows da Microsoft: http://www.microsoft.com/whdc/devtools/debugging/default.mspx

, em seguida, iniciar o utilitário GFlags, ir para a terceira aba e digite o nome do seu executável, em seguida, bateu a chave. Marque a opção PageHeap, clique em OK e você está pronto para ir.

A última coisa: quando você está feito com a depuração, nunca se esqueça de GFlags lançamento de novo, e desativar PageHeap para a aplicação. GFlags entra esta definição para o Registro (em HKLM \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Image File Execution Options \), por isso é persistente, mesmo entre as reinicializações.

Além disso, estar ciente de que usando PageHeap pode aumentar as necessidades de memória de sua aplicação tremendamente.

A maneira de fazer o que você quer é BE o alocador. Se você filtrar todos os pedidos, e depois gravá-las para fins de depuração, então você pode descobrir o que você quer quando a memória é free'd.

Além disso, você pode verificar no final do programa para ver se todos os blocos alocados foram libertados, e se não, lista-los. Uma biblioteca ambicioso deste tipo poderia mesmo tomar FUNÇÃO e LINHA parâmetros através de uma macro para que você saiba exatamente onde você está com vazamento de memória.

Finalmente, MSVCRT da Microsoft fornece aa pilha debuggable que tem muitas ferramentas úteis que você pode usar em sua versão de depuração para encontrar problemas de memória: http://msdn.microsoft.com/en-us/library/bebs9zyz.aspx

No Linux, você pode usar valgrind para encontrar muitos erros. http://valgrind.org/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top