No livro C#12 In A Nutshell, os autores escrevem este código:
UnsafeClass a = new UnsafeClass ("Christian Troy");
unsafe struct UnsafeUnicodeString
{
public short Length;
public fixed byte Buffer[30];
}
unsafe class UnsafeClass
{
UnsafeUnicodeString uus;
public UnsafeClass (string s)
{
uus.Length = (short)s.Length;
fixed (byte* p = uus.Buffer)
for (int i = 0; i < s.Length; i++)
p[i] = (byte) s[i];
}
}
Eles então mencionam
A palavra-chave fixed também é usada neste exemplo para fixar o objeto no heap que contém o buffer (que será a instância de UnsafeClass)
Não tenho certeza se entendi o que eles querem dizer / sobre o que estão falando. Se estão falando sobre a
, por que precisariam a
ser fixados. Se estão falando sobre uus
, por que diriam "fixar o objeto no heap", uus
deveria estar na pilha, certo? (apenas tipos de valor) Ou talvez estejam falando sobre p
? Mas p
está na pilha, se entendi corretamente?
Quando usamos
fixed
dessa forma, o buffer é fixado onde quer que esteja ; isso poderia estar potencialmente na pilha (nesse caso, nada realmente muda, embora as etapas ainda sejam observadas), mas neste casouus.Buffer
se refere a um campo de um objeto . O que acabamos tendo é um local especial que é um "ponteiro interior" para um endereço dentro de um objeto que está no heap (aUnsafeClass
instância). OUnsafeUnicodeString
não está na pilha em nenhum ponto aqui - apenas o endereço do campo (em um objeto específico) é carregado.São esses locais especiais que indiretamente fixam o objeto; o GC é necessário para localizar todos esses locais especiais na pilha (ao ativar o GC) e garantir que o objeto mais largo seja tratado como fixado.
O objeto (o mesmo objeto que
a
aponta para) precisa ser fixado porque é onde os dados estão - como um campo dentro desse objeto. Se não fosse fixado, o ponteirop
estaria apontando para o local errado - este é um ponteiro não gerenciado e ponteiros não gerenciados não são ajustados pelo GC durante as movimentações (o ponto é que você deve ajudar o GC a não movê-los , que é o que estamos fazendo aqui).