comportamento incerto de um fora ponteiro fixo da declaração fixo
-
21-08-2019 - |
Pergunta
Alguém pode me explicar por que o abaixo código C # não falhar? Por que Visual Studio realmente permitir que compilá-lo? O meu entendimento é que eu estou recebendo um ponteiro fixo, mas é fixada apenas na declaração 'fixo'. Quando o ponteiro é devolvido a partir da função 'Foo', podem ser recolhidos a matriz 'AR'. Eu, então, forçar GC para realmente fazer isso, mas a escrita consecutiva à memória (que agora é desalocada) não causa nenhum erro.
class Program
{
static unsafe byte* Foo()
{
byte[] ar = new byte[100];
fixed (byte* ptr = ar)
{
return ptr;
}
}
static unsafe void Main(string[] args)
{
byte* ptr = Foo();
GC.Collect();
for (int t = 0;;++t) ptr[t%100] = 0;
}
}
Solução
Eric é certo, mas a resposta que você provavelmente vai querer ouvir é que "às vezes é útil para reter o exterior endereço da declaração fixo".
Talvez a memória daquele ponteiro já está fixado por uma outra declaração fixo em algum outro lugar, e faz sentido para devolvê-lo? O compilador não está tentando adivinhar-lo e dar avisos ruidosos.
Dito isso, eu espero que CodeAnalysis ou outras ferramentas avançadas iria intervir aqui onde o compilador está permitindo que você cortar seu próprio pé.
Outras dicas
Só porque a memória é liberada não significa que a escrita para que causaria um erro de qualquer tipo. Quando o coletor de lixo recupera a memória, ele só marca como livre em sua mapa de memória interna -. Não dá-lo de volta para o sistema operacional de imediato, por isso é memória ainda válida para o seu processo de utilização
Claro, usando um fora ponteiro do bloco fixo pois é uma muito má idéia -. Não fazê-lo