Menu
CoddyTech

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 precisa ser liberado eventualmente. Assim como escrevemos uma função create_ para cuidar da alocação, escrevemos uma função free_ para cuidar da limpeza. Esse é o padrão de destrutor.

A principal ideia é que a liberação deve acontecer 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);          // Libere primeiro o membro interno
    free(p);                // Depois libere 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);  // Libere os recursos ao terminar

Esse padrão garante que toda a memória seja liberada corretamente. Sem ele, cada objeto que você criar causaria vazamento de memória até que o 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ê vai praticar a escrita de uma função destrutora que libera corretamente toda a memória alocada, na ordem certa.

Você criará três arquivos:

  • movie.h: Declare uma estrutura 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 um destrutor free_movie, que recebe um ponteiro para Movie. Use proteções de inclusão com o símbolo MOVIE_H.
  • movie.c: Implemente as duas funções. Seu construtor deve alocar memória para a estrutura e sua string de título (não se esqueça do terminador nulo). Seu destrutor deve liberar a memória na ordem inversa à da alocação: primeiro a string interna title e, depois, a própria estrutura. Inclua uma verificação de NULL no início do destrutor, por segurança.
  • main.c: Crie um filme, exiba suas informações e, em seguida, libere a memória corretamente.

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, imprimir suas informações e, em seguida, chame free_movie para liberar toda a memória. Depois de liberar a memória, imprima uma mensagem de confirmação.

Imprima 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: o segredo para um destrutor correto é liberar a memória na ordem inversa. O que o construtor aloca primeiro é liberado por último, e o que ele aloca por último é liberado primeiro.

Experimente você mesmo

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

int main() {
    char title[100];
    int year;
    
    // Leia a entrada
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: Crie um filme usando create_movie
    
    // TODO: Imprima as informações do filme no formato:
    // Filme: {title} ({year})
    
    // TODO: Libere a memória do filme usando free_movie
    
    // TODO: Imprima "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