Cấp phát động với malloc()
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 32 trên 63.
Giờ bạn sẽ tìm hiểu về malloc(), hàm chính dùng để yêu cầu bộ nhớ từ heap trong khi chương trình chạy. Hàm malloc() là viết tắt của "memory allocation" và cho phép bạn cấp phát bộ nhớ động khi cần, thay vì khai báo các biến có kích thước cố định tại thời điểm biên dịch.
Hàm (function) malloc() nhận một đối số: số byte bạn muốn cấp phát. Hàm trả về một con trỏ void (void pointer) trỏ đến khối bộ nhớ đã cấp phát hoặc NULL nếu việc cấp phát thất bại. Vì hàm trả về con trỏ void, bạn có thể gán trực tiếp con trỏ này cho một con trỏ có kiểu cụ thể; trong C, việc ép kiểu là tùy chọn, không giống C++, nơi bạn cần ép kiểu.
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // Cấp phát bộ nhớ cho một số nguyên
// ptr hiện trỏ đến vùng nhớ có thể chứa một số nguyênƯu điểm chính của
malloc()là tính linh hoạt: bạn có thể yêu cầu chính xác lượng bộ nhớ cần dùng khi chương trình đang chạy, và lượng bộ nhớ này vẫn khả dụng cho đến khi bạn chủ động giải phóng nó. Điều này đặc biệt hữu ích khi bạn chưa biết chương trình sẽ cần bao nhiêu bộ nhớ cho đến lúc chạy.
Nhớ thêm <stdlib.h> để dùng malloc(). Trong C, bạn không bắt buộc phải ép kiểu con trỏ void được trả về vì con trỏ này tự động chuyển sang kiểu dữ liệu mà bạn gán cho nó.
Thử thách
DễViết chương trình C minh họa cách cấp phát bộ nhớ động bằng malloc() để tạo và thao tác với một số nguyên duy nhất trên heap. Chương trình của bạn cần:
- Dùng
malloc()để cấp phát động bộ nhớ cho một số nguyên - Ép con trỏ void được trả về thành con trỏ số nguyên
- Đọc một giá trị số nguyên từ đầu vào của người dùng
- Lưu giá trị đầu vào vào vùng nhớ được cấp phát động bằng toán tử giải tham chiếu
- In giá trị đã lưu theo định dạng:
Stored value: [value] - Tính bình phương của giá trị và lưu vào cùng vị trí bộ nhớ
- In giá trị bình phương theo định dạng:
Squared value: [value]
Nhớ thêm tiêu đề <stdlib.h> để dùng malloc(). Chương trình của bạn cần minh họa quy trình cơ bản của việc cấp phát bộ nhớ động: yêu cầu bộ nhớ từ heap, dùng bộ nhớ đó để lưu trữ và thao tác với dữ liệu, rồi làm việc với vùng nhớ đã cấp phát thông qua các thao tác với con trỏ.
Ví dụ, nếu người dùng nhập 7, đầu ra của bạn sẽ là:
Stored value: 7
Squared value: 49Thử thách này giới thiệu cho bạn khái niệm cơ bản về cấp phát bộ nhớ động, trong đó bộ nhớ được yêu cầu khi chương trình chạy thay vì được cố định lúc biên dịch, giúp chương trình linh hoạt hơn trong việc sử dụng bộ nhớ.
Tự làm thử
#include <stdio.h>
#include <stdlib.h>
int main() {
// Đọc đầu vào
int input_value;
scanf("%d", &input_value);
// TODO: Viết code bên dưới
// 1. Dùng malloc() để cấp phát bộ nhớ cho một số nguyên
// 2. Ép kiểu con trỏ trả về thành int*
// 3. Lưu giá trị đầu vào vào vùng nhớ đã cấp phát
// 4. In ra giá trị đã lưu
// 5. Tính bình phương và lưu vào cùng vị trí
// 6. In ra giá trị bình phương
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