Prova de vazamento de memória em todo programa C

Uma postagem de blog em tom de brincadeira propõe “corrigir” vazamentos de memória em C interceptando `malloc` e armazenando cada alocação em uma lista global, para que detectores de vazamento vejam tudo como ainda alcançável — ao custo de realmente vazar e corromper memória. Os comentaristas explicam por que isso é inseguro e enganoso, contrastam com ferramentas reais como Valgrind e LeakSanitizer e usam o tema para discutir quando não liberar memória é aceitável (processos de curta duração, arenas, FaaS) e quando gerenciamento robusto de memória, RAII ou coleta de lixo são essenciais.

Seriedade da proposta

  • Muitos comentaristas veem o post claramente como uma piada, feita para demonstrar quão facilmente detectores de vazamento podem ser enganados, e não como uma técnica de produção.
  • Outros observam que o código parece plausível o suficiente para que programadores C menos experientes possam confundi-lo com uma solução real, o que os preocupa.

Crítica técnica ao wrapper de malloc “bigbucket”

  • O wrapper apenas rastreia alocações em uma lista global; ele nunca remove entradas, mesmo quando o código do usuário chama free.
  • Isso produz vazamentos reais: a memória heap usada pela lista de rastreamento cresce sem limite, e os ponteiros armazenados tornam-se pendentes após free.
  • Ele pode esgotar a memória mesmo para programas que liberam tudo corretamente em um loop.
  • Não é thread-safe e paga um custo alto ao chamar dlsym em toda alocação.
  • Alguns observam que você poderia “completar” a piada redefinindo free como um no-op para evitar totalmente ponteiros pendentes.

Definição de vazamentos vs. crescimento de memória sem limite

  • Vários apontam que memória “alcançável” ainda pode ser um vazamento na prática; linguagens com GC podem vazar por meio de referências esquecidas.
  • Outros enfatizam que o que realmente importa é o consumo de memória sem limite, não se a memória é tecnicamente alcançável.

Não liberar intencionalmente em sistemas reais

  • Muitos exemplos são dados em que não liberar é intencional e aceitável: programas de curta duração, processos por requisição no estilo CGI/PHP, alocadores arena/por requisição, sistemas de HFT, alguns motores de jogos/áudio, mísseis ou sistemas embarcados especializados, e servidores que reiniciam periodicamente.
  • Alguns argumentam que liberar no encerramento do programa muitas vezes é inútil e pode até prejudicar o desempenho (por exemplo, page faults ao desmontar heaps grandes).

Ferramentas de detecção de vazamentos e estratégias práticas

  • Os comentaristas recomendam ferramentas reais como Valgrind e LeakSanitizer, além de padrões como arenas, design livre de vazamentos por módulo e liberação seletiva dos “caminhos quentes” que dominam as alocações.
  • Um truque mencionado: executar a lógica completa de limpeza apenas quando estiver sob um verificador de vazamentos (por exemplo, detectando o Valgrind em tempo de execução).

Questões meta e de medição

  • O tópico invoca repetidamente a ideia de que, se você otimizar apenas para “sem vazamentos sob a ferramenta X”, as pessoas vão manipular essa métrica (lei de Goodhart).
  • Vários observam que, em grandes bases de código, vazamentos reais são mais raros do que inchaço de memória por dados retidos mas não usados, o que é mais difícil de encontrar e afeta todas as linguagens.