Limpando lixo da memória em C

(Última atualização em: 20 de janeiro de 2017)

O Thalles, então aluno do terceiro curso de C que explora recursos mais avançados dessa linguagem, fez uma pergunta interessante no fórum com relação à parte que tratamos da limpeza da memória no momento da alocação.

É bem comum que, ao procurarmos informação a respeito de limpeza da memória encontremos posts que indicam três funções diferentes: memset, fflush e setbuf. Veja aqui como elas são diferentes e para quê usar cada uma delas!

memset

A razão pela qual usamos o memset nesse curso é apenas para termos certeza de que o pedaço de memória que vamos usar esteja sem “lixo” — isto é, para que saibamos que tudo o que tem nessa posição de memória são, no exemplo do curso, zeros:

memset(&variavel, 0, sizeof(SUA_STRUCT));

Isso é importante porque se esquecermos de colocar informação nessa variável, poderíamos, sem querer, usar o lixo que já estava naquela posição de memória e, com ele, ter resultados bem estranhos.

Pense, por exemplo, em um programa que guardasse a query que você faria para o banco de dados em uma variável. Você vai precisar criar essa variável e colocar nela a string da query. Aí, por um acaso, aquele pedaço de memória que você alocou tem um lixo onde vemos os caracteres kjs83khas; drop database; bem no trecho que seria usado como a query. Aí, por um novo acaso, o desenvolvedor esquece de preencher a memória com a query correta e esse trecho de lixo é rodado.

Sem querer, por uma grande coincidência e azar, poderíamos apagar todas as tabelas do banco de dados que acessamos! Para garantir que não vamos ter lixo perigoso em variáveis, usamos o memset.

fflush

A função fflush é usada para forçar seu programa a escrever agora tudo o que está no buffer que você passar como parâmetro – por exemplo o da saída de dados padrão.

As linguagens usualmente criam buffers para atividades que envolvam entrada e saída de dado (IO operations) porque essas são particularmente demoradas e frequentemente bloqueiam a execução normal do programa, enquanto estão escrevendo ou lendo.

fflush(stdout);

Se você chamar esse código, tudo o que está sendo acumulado para ser escrito quando o buffer encher será escrito agora. Isso serve, por exemplo, para garantir que toda a saída do programa será impressa antes do programa terminar!

Lembrando que ele também serve para arquivos ou qualquer tipo de buffer que você estiver usando.

setbuf

A função setbuf, por sua vez, simplesmente transforma esse buffer que mencionamos acima para um buffer que determinarmos no segundo parâmetro. Então, quando as pessoas querem jogar fora tudo o que está em um buffer, elas podem fazer:

setbuf(stdout, 0);

Após essa linha, tudo o que estava no buffer foi jogado fora e, assim, o que não tinha sido impresso não o será mais. A mesma ideia vale para a leitura:

setbuf(stdin, 0);

Esse código faria tudo o que está no buffer de leitura da entrada padrão e ainda não foi consumido, ser jogado fora. Agora, seu buffer está limpo para receber uma nova entrada de dados.


Como vimos, faz sentido que sejam três funções diferentes, apesar de todas elas, de alguma forma, limparem um trecho de memória! Mas, como qualquer dúvida de especificação, não se preocupe em decorar o que cada uma faz: é mais importante sabermos que esses três pontos podem ser limpos do que lembrar exatamente qual função usar!

E aí, gostou dessa dica? Quer aprender mais? Você provavelmente vai gostar de nossa Trilha Computação.

  • GUSTAVO RIPOSATI

    Eu tinha respondido já essa dúvida no fórum

  • Oi Gustavo,

    acontece com frequência, mesmo, de dúvidas repetidas ou muito semelhantes aparecerem no fórum! A dúvida que eu respondi era essa aqui: https://www.alura.com.br/course/introducao-a-programacao-com-c-parte-3/discussions/674442

    Aí, como a resposta acabou ficando bastante completa, transformei em um post aqui para o blog. 🙂 Você também tem respostas do fórum que poderiam se tornar posts pro blog? Manda pra’gente! 🙂

Próximo ArtigoO site do Alura está de cara nova