Dùng sizeof() để 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 33 trên 63.
Mặc dù malloc() cho phép bạn cấp phát bộ nhớ một cách linh hoạt, có một quy tắc thực hành tốt rất quan trọng giúp code của bạn dễ chuyển đổi và bảo trì hơn: dùng toán tử sizeof() để xác định số byte cần cấp phát.
Toán tử sizeof() trả về số byte cần thiết để lưu trữ một kiểu dữ liệu cụ thể trên hệ thống của bạn. Thay vì ghi cố định kích thước bằng byte, bạn có thể để sizeof() tự động tính toán kích thước chính xác:
// Thay vì đoán kích thước tính bằng byte:
int *ptr = (int*)malloc(4); // Giả định int chiếm 4 byte
// Dùng sizeof() để code chạy được trên nhiều nền tảng:
int *ptr = (int*)malloc(sizeof(int)); // Luôn chính xácCách này đặc biệt hữu ích khi cấp phát mảng. Để cấp phát chỗ cho nhiều phần tử, hãy nhân số phần tử với kích thước của mỗi phần tử:
// Cấp phát bộ nhớ cho 10 số nguyên
int *arr = (int*)malloc(10 * sizeof(int));
// Cấp phát bộ nhớ cho 5 giá trị kiểu double
double *values = (double*)malloc(5 * sizeof(double));Dùng sizeof() giúp code của bạn hoạt động chính xác trên các hệ thống khác nhau, nơi kiểu dữ liệu có thể có kích thước khác nhau, đồng thời thể hiện rõ ý định cấp phát bộ nhớ cho một số lượng phần tử cụ thể thuộc một kiểu nhất định.
Thử thách
DễViết chương trình C minh họa cách sử dụng đúng sizeof() với malloc() để cấp phát bộ nhớ động. Chương trình của bạn cần:
- Đọc một số nguyên
ntừ người dùng, biểu thị số phần tử cần cấp phát - Dùng
malloc()cùng vớisizeof()để cấp phát động bộ nhớ cho một mảng gồmngiá trị double - Ép kiểu con trỏ void được trả về thành con trỏ double
- Đọc
ngiá trị double từ người dùng và lưu chúng vào mảng đã cấp phát - Tính tổng bộ nhớ đã cấp phát, tính bằng byte, rồi in theo định dạng:
Memory allocated: [bytes] bytes - Tính và in giá trị trung bình của tất cả các giá trị với đúng 2 chữ số thập phân theo định dạng:
Average: [value] - Tìm và in giá trị lớn nhất với đúng 2 chữ số thập phân theo định dạng:
Largest: [value]
Nhớ thêm tiêu đề <stdlib.h> để dùng malloc(). Chương trình của bạn cần minh họa cách sizeof() đảm bảo cấp phát bộ nhớ chính xác, bất kể kích thước kiểu dữ liệu của hệ thống.
Ví dụ, nếu đầu vào là:
3
2.5 7.8 4.1Đầu ra của bạn cần là:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80Thử thách này củng cố tầm quan trọng của việc dùng sizeof() để giúp quá trình cấp phát bộ nhớ động có tính khả chuyển và dễ bảo trì, đồng thời tự động tính đúng số byte cần thiết cho mọi kiểu dữ liệu trên mọi hệ thống.
Tự làm thử
#include <stdio.h>
#include <stdlib.h>
int main() {
// Đọc số lượng phần tử
int n;
scanf("%d", &n);
// TODO: Viết code của bạn bên dưới
// 1. Cấp phát bộ nhớ cho n giá trị double bằng malloc() và sizeof()
// 2. Ép kiểu con trỏ trả về thành double*
// 3. Đọc n giá trị double và lưu vào mảng (array) đã cấp phát
// 4. Tính và in ra dung lượng bộ nhớ đã cấp phát, tính bằng byte
// 5. Tính và in ra giá trị trung bình với 2 chữ số thập phân
// 6. Tìm và in ra giá trị lớn nhất với 2 chữ số thập phân
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