Kiểm tra lỗi cấp phát
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 34 trên 63.
malloc() là một công cụ mạnh mẽ để cấp phát bộ nhớ động, nhưng bạn cần hiểu một thực tế quan trọng: malloc() có thể thất bại. Khi hệ thống hết bộ nhớ khả dụng, malloc() không thể đáp ứng yêu cầu của bạn và trả về NULL thay vì một địa chỉ bộ nhớ hợp lệ.
Điều này có nghĩa là mỗi khi dùng malloc(), bạn phải kiểm tra xem hàm có thành công hay không trước khi sử dụng con trỏ được trả về. Dùng con trỏ NULL sẽ khiến chương trình gặp lỗi phân đoạn và bị dừng.
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // Thoát chương trình hoặc xử lý lỗi
}
// Có thể dùng ptr ở đây một cách an toàn
*ptr = 42;Việc kiểm tra NULL này không phải là tùy chọn, mà rất cần thiết để viết các chương trình C vững chắc. Dù tình trạng cấp phát bộ nhớ thất bại hiếm khi xảy ra trên các hệ thống hiện đại, điều đó vẫn có thể xảy ra, nhất là trong môi trường hạn chế tài nguyên hoặc khi yêu cầu cấp phát lượng bộ nhớ lớn. Code C chuyên nghiệp luôn có các bước kiểm tra này để tránh sự cố và xử lý lỗi một cách phù hợp.
Thử thách
DễViết một chương trình C minh họa cách xử lý lỗi phù hợp khi dùng malloc() để cấp phát bộ nhớ động. Chương trình cần:
- Đọc một số nguyên
ntừ 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ồmnsố nguyên - Kiểm tra việc cấp phát bộ nhớ có thành công hay không bằng cách kiểm tra xem con trỏ trả về có phải là
NULLhay không - Nếu cấp phát 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 allocation successful! - Đọc
ngiá 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ả các giá trị theo định dạng:
Sum: [value] - In tổng số byte đã cấp phát theo định dạng:
Bytes allocated: [value]
Nhớ thêm tiêu đề <stdlib.h> để dùng malloc(). Chương trình cần thể hiện thực hành thiết yếu là kiểm tra lỗi cấp phát trước khi sử dụng vùng nhớ đã cấp phát.
Ví dụ, nếu đầu vào là:
4
10 20 30 40Đầu ra cần là:
Memory allocation successful!
Sum: 100
Bytes allocated: 16Thử thách này nhấn mạnh tầm quan trọng cốt yếu của lập trình phòng thủ khi làm việc với cấp phát bộ nhớ động, giúp chương trình xử lý ổn thỏa các lỗi cấp phát bộ nhớ tiềm ẩn thay vì bất ngờ gặp sự cố.
Tự làm thử
#include <stdio.h>
#include <stdlib.h>
int main() {
// Đọc số lượng số nguyên
int n;
scanf("%d", &n);
// TODO: Viết code của bạn ở đây
// Dùng malloc() để cấp phát bộ nhớ cho n số nguyên
// Kiểm tra việc cấp phát có thành công không
// Xử lý cả trường hợp thành công và thất bại
// Đọc và lưu các số nguyên
// Tính tổng và số byte đã 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