Trong bài viết này, bạn sẽ học cách quản lý bộ nhớ trong lập trình C bằng cách sử dụng các hàm thư viện chuẩn: malloc(), calloc(), free() và realloc().
Như bạn đã biết, bạn phải khai báo kích thước của một mảng trước khi bạn sử dụng nó. Do đó, mảng mà bạn khai báo có thể không đủ hoặc nhiều hơn mức cần thiết để lưu trữ dữ liệu. Để giải quyết vấn đề này, bạn có thể cấp phát bộ nhớ động.
Quản lý bộ nhớ động đề cập đến quản lý bộ nhớ thủ công. Điều này cho phép bạn thu được nhiều bộ nhớ hơn khi được yêu cầu và giải phóng bộ nhớ khi không cần thiết.
Ngôn ngữ lập trình C cung cấp một số hàm để cấp phát và quản lý bộ nhớ. Các hàm này được cài đặt trong tệp tiêu đề <stdlib.h>.
Hàm | Mô tả |
---|---|
malloc() | Phân bổ kích thước yêu cầu của byte và trả về một byte đầu tiên của không gian được phân bổ. |
calloc() | Phân bổ không gian cho một phần tử mảng, khởi tạo về 0 và sau đó trả về một con trỏ tới bộ nhớ. |
free() | Giải phóng không gian được phân bổ trước đó. |
realloc() | Thay đổi kích thước của không gian được phân bổ trước đó. |
Nội dung chính
Phân bổ bộ nhớ động
Trong khi lập trình, nếu bạn nhận thức được kích thước của một mảng, bài toán trở lên đơn giản và bạn có thể định nghĩa nó như một mảng. Ví dụ, để lưu trữ danh sách tên, với kích thước tối đa là 100 ký tự, bạn có thể định nghĩa như sau:
char name[100];
Nhưng bây giờ chúng ta hãy xem xét một tình huống mà bạn không biết về độ dài của văn bản bạn cần để lưu trữ, ví dụ, bạn muốn lưu trữ một mô tả chi tiết về một chủ đề. Ở đây chúng ta cần định nghĩa một con trỏ tới ký tự mà không cần định nghĩa bao nhiêu bộ nhớ được yêu cầu và sau đó, dựa trên yêu cầu, chúng ta có thể cấp phát bộ nhớ như trong ví dụ dưới đây:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char name[100]; char *description; strcpy(name, "Vinh"); /* phan bo bo nho dong */ description = malloc( 200 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - khong the phan bo bo nho yeu cau.\n"); } else { strcpy( description, "Vinh la mot ky su thiet ke o to."); } printf("Name = %s\n", name ); printf("Description: %s\n", description ); }
Kết quả:
Name = Vinh Description: Vinh la mot ky su thiet ke o to.
Bạn cũng có thể sử dụng calloc(); để cấp phát bộ nhớ động, với cú pháp như sau:
description = calloc( 200 * sizeof(char) );
Vì vậy, bạn có toàn quyền kiểm soát và bạn có thể truyền bất kỳ giá trị kích thước nào trong khi cấp phát bộ nhớ, không giống như các mảng khi kích thước được xác định, bạn không thể thay đổi nó.
Thay đổi kích thước và giải phóng bộ nhớ
Khi chương trình của bạn kết thúc, hệ điều hành sẽ tự động giải phóng tất cả bộ nhớ do chương trình của bạn phân phối nhưng như nó sẽ tốt hơn khi không cần bộ nhớ nữa thì bạn nên giải phóng bộ nhớ đó bằng cách gọi hàm free().
Ngoài ra, bạn có thể tăng hoặc giảm kích thước của khối bộ nhớ được cấp phát bằng cách gọi hàm realloc(). Ví dụ sau sử dụng các hàm realloc() và free()
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char name[100]; char *description; strcpy(name, "Vinh"); // phan bo bo nho dong cho description description = malloc( 50 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - khong the phan bo bo nho yeu cau.\n"); } else { strcpy( description, "Vinh la mot ky su thiet ke o to."); } printf("Name = %s\n", name ); printf("Description: %s\n", description ); // thay doi kich thuoc bo nho cua description description = realloc( description, 100 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - khong the phan bo bo nho yeu cau.\n"); } else { strcat( description, "Vinh la mot ky su thiet ke o to," " hien tai dang lam viec cho cong ty EZCar"); } printf("Description: %s\n", description ); // giai phong bo nho free(description); }
Kết quả:
Name = Vinh Description: Vinh la mot ky su thiet ke o to. Description: Vinh la mot ky su thiet ke o to.Vinh la mot ky su thiet ke o to, hien tai dang lam viec cho cong ty EZCar
Bạn có thể thử lại ví dụ trên bằng cách không phân bổ lại bộ nhớ cho description, một lỗi sẽ xảy ra.