Chương này giải thích về quản lý bộ nhớ động (dynamic memory management) trong C. 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ớ. Bạn có thể tìm thấy các hàm này trong file header <stdlib.h>.
No. | Hàm & Mô tả |
1 | void *calloc(int num, int size); Hàm này cấp phát một mảng gồm num phần tử, với mỗi phần tử có kích thước size tính theo byte |
2 | void free(void *address); Hàm này giải phóng vùng bộ nhớ được chỉ định bởi địa chỉ address. |
3 | void *malloc(size_t size); Hàm này cấp phát một mảng có kích thước size byte và không khởi tạo giá trị vùng được cấp phát này. |
4 | void *realloc(void *address, int newsize); Hàm này cấp phát lại bộ nhớ để mở rộng lên kích thước mới newsize. |
Cấp phát bộ nhớ động (Allocating Memory Dynamically)
Khi lập trình, nếu bạn biết trước kích thước của một mảng thì bạn sẽ dễ dàng định nghĩa nó là một mảng. Ví dụ: để lưu trữ tên của bất kỳ ai, tên đó có thể chứa tối đa 100 ký tự, vì vậy bạn có thể định nghĩa (define) như sau:
char name[100];
Nhưng chúng ta hãy xem xét một tình huống mà bạn không đoán được độ dài của văn bản cần lưu trữ, chẳng hạn như bạn muốn lưu trữ một mô tả thông tin chi tiết của một chủ đề. Ở đây chúng ta cần define một con trỏ tới ký tự (pointer to character) mà không cần xác định dung lượng bộ nhớ là bao nhiêu, và sau đó, tùy theo yêu cầu mà 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, "Zara Ali"); /* allocate memory dynamically */ description = malloc( 200 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcpy( description, "Zara ali a DPS student in class 10th"); } printf("Name = %s\n", name ); printf("Description: %s\n", description ); }
Sau khi đoạn code trên được biên dịch và thực thi, nó sẽ cho kết quả như sau:
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
Chương trình tương tự có thể được viết sử dụng calloc(); bạn chỉ cần thay đổi hàm malloc với calloc như sau:
calloc(200, sizeof(char));
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 (release) tất cả bộ nhớ được cấp phát bởi chương trình. Tuy nhiên, một thói quen tốt chính là khi bạn không cần sử dụng bộ nhớ nữa, thì hãy giải phóng vùng nhớ đó bằng việc gọi lệnh 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(). Chúng ta hãy kiểm tra chương trình trên một lần nữa và 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, "Zara Ali"); /* allocate memory dynamically */ description = malloc( 30 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcpy( description, "Zara ali a DPS student."); } /* suppose you want to store bigger description */ description = realloc( description, 100 * sizeof(char) ); if( description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcat( description, "She is in class 10th"); } printf("Name = %s\n", name ); printf("Description: %s\n", description ); /* release memory using free() function */ free(description); }
Bạn có thể thử ví dụ bên trên với phần tái cấp phát bộ nhớ mở rộng bị loại bỏ, và hàm strcat() sẽ trả về một lỗi (error) do trong description không đủ bộ nhớ.