Executando verificação de segurança...
2
DevOne
6 min de leitura ·

"Double memory free", mais uma vez rust em ação

Um bug muito conhecido que aparece em linguagem que atuam em um mais baixo nível como por exemplo a dupla C/C++.

O bug

Imagine que temos uma variável x, ela é um inteiro sem sinal de 32 bits (pra quem gosta de especificidade) com o valor 10:

// pseudo código

unsigned int x = 10;

Agora neste mesmo pensamento, temos uma variável y, ela recebe x:

// pseudo código

...
unsigned int y = x;

resultando no seguinte código:

unsigned int x = 10;
unsigned int y = x;

Ao fazer essa associação, a variável y está apontando para o mesmo endereço de memória da variável x, então após algum código eu preciso limpar essas variáveis da memória, então eu chamo uma função que faz essa limpeza para a variável y, e logo após chamo a mesma função para a variável x, o problema é que as duas apontam para o mesmo endereço de memória o que significa que ao tentar limpar a variável y a variável x não existe mais.
Então é ai onde o bug acontece, pois eu vou estar tentando limpar um endereço que não existe mais.


Bom, o foco aqui não é falar sobre o bug em si, mas sim como o rust faz para nos proteger de cair nessa silada.

Assumindo que você compreendeu como o bug acontece vamos para nosso próximo tópico.

Como o rust nos protege desse bug?

Bom, no rust as coisas funcionam um tanto quanto diferentes, deixe me lhe mostra com código:

exemplo 1

no exemplo acima nós temos uma variável x que é igual a 10, e logo abaixo criamos uma variável y que recebe x.

Ao rodar o programa temos o seguinte resultado

resultado do exemplo 1

Os valores são iguais, mas os endereços na memória são diferentes, isso acontece porque no caso de inteiros e outros tipos no rust, uma cópia dos dados é feita. então, a variável y recebe uma cópia da variável x.
Nesse caso o bug não acontece, pois são duas variáveis distintas.

Agora vamos dar uma olhada em uma situação interessante:

exemplo 2

esse código aparentemente deve funcionar normalmente correto?
mas ao executarmos veja só o output que temos:

resultado do exemplo 2

Obtivemos um erro.

Deixe me explicar o que aconteceu.

Quando usamos o tipo String, ao fazer essa associação de s2 = s1 a variável s2 irá apontar para o mesmo endereço de memória que a variável s1 está apontando.
Por padrão, em tempo de execução ao uma variável sair do seu escopo o rust automaticamente libera aquele espaço para nós, nesse exemplos temos duas variáveis apontando para o mesmo endereço

exemplo do comportamento das variáveis na memória

Então quando o escopo em que as variáveis s1 e s2 estão, em teoria, o rust deveria limpar esses valores, mas caso ele limpasse a variável s2 a variável s1 não existiria mais, então ele iria estar tentando liberar um endereço que não existe mais.

então para nossa segurança em tempo de compilação, após a atribuição da variável s2 para a variável s1 o compilador considera s1 inválida e não permite o uso dela após essa atribuição, nos prevenindo de causar um possível bug em nosso software.

Rust will never automatically create “deep” copies of your data. Therefore, any automatic copying can be assumed to be inexpensive in terms of runtime performance.

Espero que tenha gostado desse artigo, sinta-se livre para responder, estamos todos aprendendo! 🤩

1

Postagem bastante descritiva e pude acompanhar a linha de raciocinio com bastante entusiasmo, mas há erros de exibição infelizmente, talvez algum bug da plataforma ou um erro nos comandos para apresentação das imagens. Gostaria de parabenizar pela clareza com que escreve, de fato, Rust é uma linguagem muito inteligente, é uma linguagem sem sobra de duvida moderna e atual... Esta semana comecei a estuda-la e tem sido uma trajetória feliz.

1

Interessante, estou vendo normalmente

as imagens não apareceram?
se puder informar, vou tentar resolver

obrigado!

1

Estas não aparecem:
Resultado do exemplo 1
Exemplo 2
resultado do exemplo 2

Agora na imagem seguinte é exibida para mim como uma imagem grande e toda em branco

1