Menu
CoddyTech

Mẫu hàm hủy

Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 13 trên 61.

Mọi đối tượng được tạo bằng malloc cuối cùng đều phải được giải phóng. Cũng như ta viết hàm create_ để xử lý việc cấp phát, ta viết hàm free_ để xử lý việc dọn dẹp. Đây là mẫu hàm hủy.

Điều quan trọng cần hiểu là phải giải phóng theo thứ tự ngược lại với lúc cấp phát. Nếu hàm khởi tạo cấp phát các thành viên bên trong trước rồi mới cấp phát struct, thì hàm hủy phải giải phóng các thành viên của struct trước, sau đó mới giải phóng struct:

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

void free_person(Person *p) {
    if (p == NULL) return;  // Kiểm tra an toàn
    free(p->name);          // Giải phóng thành viên bên trong trước
    free(p);                // Sau đó giải phóng chính struct
}

Việc kiểm tra NULL ở đầu giúp tránh sự cố nếu ai đó vô tình truyền vào một con trỏ (pointer) không hợp lệ. Sau khi giải phóng chuỗi name bên trong, ta giải phóng chính cấu trúc đó. Nếu giải phóng p trước, ta sẽ mất quyền truy cập vào p->name và gây rò rỉ bộ nhớ.

Cách dùng hàm hủy rất đơn giản:

Person *alice = create_person("Alice", 30);
// ... sử dụng alice ...
free_person(alice);  // Giải phóng bộ nhớ sau khi dùng xong

Mẫu này đảm bảo toàn bộ bộ nhớ được giải phóng đúng cách. Nếu không có nó, mọi đối tượng bạn tạo ra sẽ làm rò rỉ bộ nhớ cho đến khi chương trình cạn bộ nhớ.

challenge icon

Thử thách

Dễ

Hãy tạo một module Movie minh họa toàn bộ vòng đời của đối tượng: từ tạo đến hủy. Bạn sẽ thực hành viết hàm hủy để giải phóng đúng cách toàn bộ bộ nhớ đã cấp phát, theo đúng thứ tự.

Bạn sẽ tạo ba tệp:

  • movie.h: Khai báo một cấu trúc Movie gồm hai thành viên: char *title (một chuỗi được cấp phát động) và int year. Khai báo cả hàm khởi tạo create_movie, nhận tiêu đề và năm, lẫn hàm hủy free_movie, nhận một con trỏ Movie. Dùng include guard với ký hiệu MOVIE_H.
  • movie.c: Triển khai cả hai hàm. Hàm khởi tạo cần cấp phát bộ nhớ cho cấu trúc và chuỗi tiêu đề (đừng quên ký tự kết thúc chuỗi null). Hàm hủy phải giải phóng bộ nhớ theo thứ tự ngược với thứ tự cấp phát: trước tiên là chuỗi title bên trong, sau đó là chính cấu trúc. Để an toàn, hãy kiểm tra NULL ngay đầu hàm hủy.
  • main.c: Tạo một bộ phim, hiển thị thông tin của bộ phim, sau đó giải phóng bộ nhớ đúng cách.

Bạn sẽ nhận hai đầu vào: tiêu đề phim (một chuỗi) và năm phát hành (một số nguyên).

Trong tệp main, dùng create_movie để tạo một bộ phim mới, in thông tin của bộ phim, sau đó gọi free_movie để giải phóng toàn bộ bộ nhớ. Sau khi giải phóng, in một thông báo xác nhận.

In đầu ra theo định dạng sau:

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

Ví dụ, với đầu vào Inception và 2010, đầu ra sẽ là:

Movie: Inception (2010)
Memory freed

Hãy nhớ: bí quyết để viết hàm hủy đúng cách là giải phóng theo thứ tự ngược lại. Thành phần nào được hàm khởi tạo cấp phát trước tiên thì được giải phóng sau cùng, còn thành phần nào được cấp phát sau cùng thì được giải phóng trước tiên.

Tự làm thử

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

int main() {
    char title[100];
    int year;
    
    // Đọc đầu vào
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: Tạo một bộ phim bằng create_movie
    
    // TODO: In ra thông tin bộ phim theo định dạng:
    // Movie: {title} ({year})
    
    // TODO: Giải phóng bộ nhớ của bộ phim bằng free_movie
    
    // TODO: In ra "Memory freed"
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C online