Giải phóng bộ nhớ với free()
Thuộc phần Logic và luồng điều khiển trong hành trình C của Coddy. Bài học 35 trên 63.
Khi cấp phát bộ nhớ động bằng malloc(), bộ nhớ đó vẫn được cấp phát cho đến khi bạn chủ động giải phóng nó. Hàm (function) free() giúp bạn trả lại bộ nhớ được cấp phát động cho hệ thống khi dùng xong.
Hàm free() nhận một đối số: con trỏ đến khối bộ nhớ mà bạn muốn giải phóng. Đây phải là cùng con trỏ mà malloc() (hoặc các hàm liên quan như calloc()) đã trả về.
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // Cấp phát bộ nhớ
*ptr = 42; // Sử dụng bộ nhớ
free(ptr); // Giải phóng bộ nhớ khi dùng xongKhông gọi free() sẽ gây ra hiện tượng gọi là rò rỉ bộ nhớ. Bộ nhớ đã cấp phát vẫn bị chương trình của bạn giữ lại dù bạn không còn sử dụng nữa. Trong các chương trình chạy lâu hoặc cấp phát bộ nhớ nhiều lần, những chỗ rò rỉ này có thể chiếm hết bộ nhớ hệ thống hiện có và gây ra vấn đề về hiệu năng hoặc khiến chương trình bị lỗi.
Hãy nhớ: mỗi malloc() cần có một free() tương ứng. Việc ghép cặp này rất cần thiết để quản lý bộ nhớ có trách nhiệm khi lập trình bằng C.
Thử thách
DễViết chương trình C minh họa toàn bộ vòng đời của việc cấp phát và giải phóng bộ nhớ động. Chương trình cần:
- Đọc một số nguyên
counttừ người dùng, biểu thị số lượng số nguyên cần lưu trữ - Dùng
malloc()cùng vớisizeof()để cấp phát động bộ nhớ cho một mảng gồmcountsố nguyên - Kiểm tra xem việc cấp phát bộ nhớ có thành công không. Nếu thất bại, in ra
Memory allocation failed!rồi kết thúc chương trình - Nếu cấp phát thành công, in ra
Memory allocated successfully! - Đọc
countgiá trị số nguyên từ người dùng và lưu vào mảng đã cấp phát - Tính và in tổng của tất cả giá trị theo định dạng:
Sum: [value] - Tìm và in giá trị lớn nhất theo định dạng:
Maximum: [value] - Dùng
free()để giải phóng bộ nhớ - In ra
Memory freed successfully!để xác nhận đã dọn dẹp
Nhớ thêm tiêu đề <stdlib.h> để dùng malloc() và free(). Thử thách này minh họa cách kết hợp thiết yếu giữa malloc() và free() để tránh rò rỉ bộ nhớ trong chương trình.
Ví dụ, nếu đầu vào là:
4
15 8 23 12Đầu ra của bạn sẽ là:
Memory allocated successfully!
Sum: 58
Maximum: 23
Memory freed successfully!Thử thách này củng cố khái niệm quan trọng rằng bạn phải giải phóng đúng cách mọi khối bộ nhớ được cấp phát động khi không còn cần dùng đến, qua đó hoàn tất chu trình quản lý bộ nhớ có trách nhiệm trong lập trình C.
Tự làm thử
#include <stdio.h>
#include <stdlib.h>
int main() {
int count;
// Đọc số lượng số nguyên cần lưu trữ
scanf("%d", &count);
// TODO: Viết code của bạn bên dưới
// 1. Cấp phát bộ nhớ bằng malloc() với sizeof()
// 2. Kiểm tra xem việc cấp phát có thành công không
// 3. Đọc các giá trị số nguyên và lưu lại
// 4. Tính tổng và tìm giá trị lớn nhất
// 5. Giải phóng bộ nhớ đã cấp phát
return 0;
}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 Logic và luồng điều khiển
1Nền tảng về con trỏ
Con trỏ là gì?Khai báo con trỏToán tử lấy địa chỉ (&)Toán tử giải tham chiếu (*)Con trỏ NULLÔn tập: kiến thức cơ bản về con trỏ4Dự án: Công cụ xử lý văn bản đơn giản
Tổng quan dự ánĐếm ký tự2Con trỏ và mảng
Tên mảng dưới dạng con trỏPhần tử mảng và con trỏPhép toán con trỏSo sánh con trỏÔn tập: duyệt mảng bằng con trỏ5Con trỏ và hàm
Truyền theo giá trịTruyền con trỏ vào hàmSửa đổi biến qua con trỏVí dụ kinh điển: hoán đổiTruyền mảng vào hàmÔn tập: đối số con trỏ hàm3Mảng ký tự và chuỗi
Chuỗi dưới dạng mảng charKý tự kết thúc nullNhập chuỗi bằng scanfDùng strlen()Dùng strcpy()Dùng strcat()Dùng strcmp()Ôn tập: các hàm xử lý chuỗi cơ bản6Quản lý bộ nhớ
Bộ nhớ ngăn xếp và bộ nhớ heapCấp phát động với malloc()Dùng sizeof() để cấp phátKiểm tra lỗi cấp phátGiải phóng bộ nhớ với free()Cấp phát với calloc()Ôn tập: Mảng động9Dự án: Nhập thông tin liên hệ đơn giản
Định nghĩa struct ContactHàm tạo liên hệTự luyện tập: Trình biên dịch C online