Pergunta

Dado um ponteiro para alguma variável .. há uma maneira para verificar se ele foi estaticamente ou dinamicamente alocados ??

Foi útil?

Solução

Citando o seu comentário:

im fazendo um método que basicamente se livrar de um struct. ele tem um membro de dados que é um ponteiro para algo que pode ou não ser malloced .. dependendo de qual, eu gostaria de livrá-lo

A maneira correta é adicionar outro membro para a estrutura:. Um ponteiro para uma função deallocation

Não é apenas estática contra a alocação dinâmica. Há vários possíveis allocators, dos quais malloc() é apenas um.

No Unix-like sistemas, poderia ser:

  • Uma variável estática
  • Na pilha
  • Na pilha, mas alocada dinamicamente (ou seja alloca())
  • No montão, alocado com malloc()
  • No montão, alocado com new
  • na pilha, no meio de uma matriz alocada dinamicamente com new[]
  • na pilha, dentro de um struct alocado com malloc()
  • na pilha, dentro de uma classe base de um objeto alocado com new
  • atribuídos com mmap
  • atribuídos com um alocador personalizado
  • Muitos mais opções, incluindo várias combinações e variações do acima

No Windows, você também tem vários tempos de execução, LocalAlloc, GlobalAlloc, HeapAlloc (com vários montes que você pode criar facilmente), e assim por diante.

Você deve sempre liberar memória com a função de liberação correto para o alocador você usou. Então, ou a parte do programa responsável por alocar a memória também deve liberar a memória, ou você deve passar a função de liberação correta (ou um invólucro em torno dele) para o código que irá liberar a memória.

Você também pode evitar toda a questão por qualquer exigindo o ponteiro para sempre ser alocados com um alocador específica ou fornecendo o alocador-se (na forma de uma função para alocar a memória e, possivelmente, uma função para liberá-lo). Se você fornecer o alocador de si mesmo, você ainda pode usar truques (como ponteiros marcados) para permitir um para também usar alocação estática (mas não vou entrar em detalhes desta abordagem aqui).

Raymond Chen tem um post sobre isso (Windows-centric, mas os conceitos são o mesmo em todos os lugares): alocar e liberar memória para além das fronteiras do módulo

Outras dicas

O ACE biblioteca faz isso todo o lugar. Você pode ser capaz de verificar como eles fazem isso. Em geral, você provavelmente não deveria precisar fazer isso em primeiro lugar embora ...

Uma vez que a pilha, a pilha, e área de dados estáticos, geralmente ocupam diferentes faixas de memória, é possível com conhecimento íntimo do mapa de memória do processo, a olhar para o endereço de e determinar qual a área de alocação que se encontra. Esta técnica é tanto arquitetura e compilador específico, por isso faz portar seu código mais difícil.

A maioria libc malloc implementações de trabalho, armazenando um cabeçalho antes de cada bloco de memória retornou que tem campos (para ser usado pela chamada free ()) que tem informações sobre o tamanho do bloco, bem como um valor 'magia'. Este valor magia é para proteger contra o usuário acidentalmente excluir um ponteiro que não foi alloc'd (ou libertar um bloco que foi substituído pelo usuário). É muito específica do sistema assim que você tem que olhar para a implementação de sua biblioteca libc para ver exatamente o valor magia estava lá.

Uma vez que você sabe disso, você mover o dado de volta ponteiro para ponto no cabeçalho e, em seguida, verifique se o valor mágico.

Você pode ligar para malloc (em si), como os depuradores malloc fazer, usando LD_PRELOAD ou algo assim? Se assim for, você poderia manter uma tabela de todos os ponteiros alocados e usar isso. Caso contrário, eu não tenho certeza. Existe uma maneira de obter a informação da contabilidade de malloc?

Não como um recurso padrão.
A versão de depuração de sua biblioteca malloc pode ter alguma função para fazer isso.

Você pode comparar seu endereço para algo que você sabe que é estático, e dizer que é malloced só se for muito longe, se você sabe o escopo deve estar vindo, mas se o seu âmbito é desconhecida, você não pode realmente confiar isso.

1.) Obter um arquivo de mapa para o código u ter.

atributos endereço inicial da memória (pilha, montão, global0, o tamanho do bloco, leitura e escrita desse bloco de memória 2) A plataforma de destino processo / hardware subjacente deve ter um arquivo de mapa de memória que normalmente indica. p>

3.) Depois de obter o endereço do objeto (variável de ponteiro) do arquivo mao em 1.) tentar ver qual bloco esse endereço cai. u pode ter alguma idéia.

= AD

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