Menu
Coddy logo textTech

Padrão de Destrutor

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 13 de 61.

Todo objeto criado com malloc deve ser eventualmente liberado. Assim como escrevemos uma função create_ para lidar com a alocação, escrevemos uma função free_ para lidar com a limpeza. Esse é o padrão destrutor.

A ideia fundamental é que a liberação deve ocorrer na ordem inversa da alocação. Se o seu construtor alocou primeiro os membros internos e depois a própria struct, o destrutor deve liberar primeiro os membros da struct e, em seguida, a struct:

typedef struct {
    char *name;
    int age;
} Person;

void free_person(Person *p) {
    if (p == NULL) return;  // Verificação de segurança
    free(p->name);          // Libera o membro interno primeiro
    free(p);                // Depois libera a própria struct
}

A verificação de NULL no início evita falhas caso alguém passe acidentalmente um ponteiro inválido. Depois de liberar a string interna name, liberamos a própria struct. Se liberássemos p primeiro, perderíamos o acesso a p->name e causaríamos um vazamento de memória.

Usar o destrutor é simples:

Person *alice = create_person("Alice", 30);
// ... use alice ...
free_person(alice);  // Limpe quando terminar

Este padrão garante que toda a memória seja devidamente liberada. Sem ele, cada objeto que você criar vazaria memória até que seu programa ficasse sem memória.

challenge icon

Desafio

Fácil

Vamos criar um módulo Movie que demonstra o ciclo de vida completo de um objeto: tanto a criação quanto a destruição. Você praticará como escrever uma função destrutora que libera corretamente toda a memória alocada, na ordem correta.

Você criará três arquivos:

  • movie.h: Declare uma struct Movie com dois membros: char *title (uma string alocada dinamicamente) e int year. Declare tanto um construtor create_movie, que recebe um título e um ano, quanto uma destrutora free_movie, que recebe um ponteiro para Movie. Use guardas de inclusão com o símbolo MOVIE_H.
  • movie.c: Implemente ambas as funções. Seu construtor deve alocar memória para a struct e para sua string de título (não se esqueça do terminador nulo). Sua destrutora deve liberar a memória na ordem inversa da alocação: primeiro a string interna title, depois a própria struct. Inclua uma verificação de NULL no início da sua destrutora por segurança.
  • main.c: Crie um filme, exiba suas informações e depois libere corretamente a memória.

Você receberá duas entradas: o título do filme (uma string) e o ano de lançamento (um inteiro).

Em seu arquivo principal, use create_movie para criar um novo filme, exiba suas informações e depois chame free_movie para liberar toda a memória. Após liberar a memória, exiba uma mensagem de confirmação.

Exiba a saída neste formato:

Movie: {title} ({year})
Memory freed

Por exemplo, com as entradas Inception e 2010, a saída seria:

Movie: Inception (2010)
Memory freed

Lembre-se: a chave para uma destrutora adequada é liberar na ordem inversa. O que quer que seu construtor aloque primeiro será liberado por último, e o que quer que ele aloque por último será liberado primeiro.

Experimente você mesmo

#include <stdio.h>
#include <stdlib.h>
#include "movie.h"

int main() {
    char title[100];
    int year;
    
    // Ler entrada
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: Criar um filme usando create_movie
    
    // TODO: Imprimir as informações do filme no formato:
    // Movie: {title} ({year})
    
    // TODO: Liberar o filme usando free_movie
    
    // TODO: Imprimir "Memory freed"
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online