Limpando lixo da memória em C

Limpando lixo da memória em C

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.

Banner da Escola de Programação: Matricula-se na escola de Programação. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

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!

Veja outros artigos sobre Programação