Một khía cạnh khá là quan trọng trong lập trình c đó là quản lí bộ nhớ động và việc quản lý bộ nhớ động cho phép chương trình của chúng ta sử dụng bộ nhớ một cách linh hoạt hơn. Và các hàm dùng để quản lí bộ nhớ động gồm 'malloc', 'calloc', 'realloc', và 'free'. Vậy các hàm này chúng có nhiệm vụ gì trong bộ nhớ động ? Để giải đáp thắc mắc đó chúng ta sẽ đi thẳng vào vấn đề .
I. Bộ nhớ động
KN : Bộ nhớ động (dynamic memory) trong lập trình C đề cập đến việc cấp phát và giải phóng bộ nhớ trong thời gian chạy của chương trình (runtime). Và bộ nhớ động giúp chương trình áp dụng tài nguyên một cách linh hoạt và chỉ sử dụng bộ nhớ khi cần thiết và giải phóng nó một cách hợp lí.
Chức năng của bộ nhớ động :
-
Tối ưu hóa tài nguyên
-
Quản lý dữ liệu phức tạp
-
Giúp chúng ta sử dụng bộ nhớ một cách lính hoạt và hiệu quả
Các hàm trong bộ nhớ động bao gồm :
-
'malloc'
-
'calloc'
-
'realloc'
-
'free'
II. Hàm 'malloc'
Hàm malloc (memory allocation) dùng để cung cấp một khối bộ nhớ có kích thước cụ thể và trả về con trỏ đến khối bộ nhớ đó
Đặc điểm:
Hàm malloc sẽ trả về con trỏ tới khối bộ nhớ được chúng ta cung cấp. Nếu không cung cấp bộ nhớ, kết quả trả về là NULL.
Cú pháp:
void *malloc(size_t size);
size: Kích thước của khối bộ nhớ cần cấp phát ( thường tính bằng byte).
Ví dụ : In ra 5 số nguyên dương (Yêu cầu tạo 1 bộ nhớ động và in ra 5 số từ 1 đến 5 )
#include <stdio.h>
#include <stdlib.h> int main() { int *yii = (int *)malloc(5 * sizeof(int)); // Cấp phát bộ nhớ cho 5 số nguyên if (yii == NULL) { printf("Khong the cung cap bo nho cho ban.\n"); return 1; } for (int i = 0; i < 5; i++) { // Khởi tạo và in giá trị yii[i] = i + 1; printf("%d ", yii[i]); } free(yii); // Giải phóng bộ nhớ return 0; }
III. Hàm 'calloc'
Hàm 'calloc' (hay còn gọi là : contiguous allocation) cũng được sử dụng để cấp phát bộ nhớ động, nhưng khác với malloc, 'calloc' nó khởi tạo tất cả các phần tử trong khối bộ nhớ về 0 (Tất cả giá trị trả về bằng 0).
Đặc điểm:
*Hàm calloc trả về con trỏ tới khối bộ nhớ được cấp phát. Nếu không cấp phát được bộ nhớ, nó trả về NULL.
*Bộ nhớ được cấp phát bởi calloc sẽ cho ra tất cả các giá trị bằng 0.
Cú pháp:
void *calloc(size_t num, size_t size);
num: Số lượng phần tử cần cấp phát.
size: Kích thước của mỗi phần tử (tính bằng byte).
Ví dụ : In ra 5 số nguyên (Yêu cầu Tạo một bộ nhớ động in ra các giá trị và tất cả các giá trị phần tử đó phải quy về bằng 0)
#include <stdio.h>
#include <stdlib.h> int main() { int *ban = (int *)calloc(5, sizeof(int)); // Cấp phát bộ nhớ và khởi tạo về 0 cho 5 số nguyên if (ban == NULL) { printf("Khong cung cap bat ki bo nho nao.\n"); return 1; } for (int i = 0; i < 5; i++) {// In ra giá trị printf("%d ", ban[i]); } free(ban); // Giải phóng bộ nhớ return 0;
}
IV. Hàm realloc
Hàm realloc (hay còn goij là reallocation) được sử dụng để thay đổi kích thước của khối bộ nhớ đã được cấp phát trước đó bởi malloc, calloc. Nó có thể mở rộng hoặc thu nhỏ bộ nhớ được cung cấp.
Đặc điểm:
Hàm realloc đưa con trỏ tới khối bộ nhớ với kích thước mới. Nếu không cấp phát được bộ nhớ, nó trả về NULL, và khối bộ nhớ cũ vẫn không thay đổi
Nếu kích thước mới lớn hơn kích thước cũ, phần bổ sung của bộ nhớ không được khởi tạoi .
Nếu kích thước mới nhỏ hơn kích thước cũ, phần bộ nhớ dư thừa sẽ bị cắt bỏ.
Cú pháp:
void *realloc(void *ptr, size_t size);
ptr: Con trỏ tới khối bộ nhớ đã được cấp phát trước đó. Nếu ptr là NULL, realloc hoạt động giống như malloc.
size: Kích thước mới của khối bộ nhớ (tính bằng byte).
Ví dụ : In ra 5 số nguyên (Yêu cầu thay đổi kích thước bộ nhớ)
#include <stdio.h>
#include <stdlib.h> int main() { // Cung cấp một mảng 5 số nguyên int *mang = (int *)malloc(5 * sizeof(int)); if (mang == NULL) { printf("Khong cung cap bo nho.\n"); return 1; } printf("Bo nho ban dau: \n"); // In ra bộ nhớ ban đầu for (int i = 0; i < 5; i++) { mang[i] = i + 1; printf("%d ", mang[i]); } mang = (int *)realloc(mang, 10 * sizeof(int));// Thay đổi kích thước mảng lên 10 số nguyên bằng hàm realloc if (mang == NULL) { printf("Khong the cung cap lai bo nho.\n"); return 1; } printf("\nBo nho sau khi mo rong: "); // Sử dụng bộ nhớ đã được mở rộng for (int i = 5; i < 10; i++) { mang[i] = i + 1; printf("%d ", mang[i]); } printf("\n"); free(mang); // Giải phóng bộ nhớ return 0;
}
V. Hàm 'free'
Hàm free là một phần quan trọng trong việc quản lý bộ nhớ động trong C. Nó được sử dụng để giải phóng bộ nhớ đã được cấp phát bởi các hàm như malloc, calloc, và realloc.
Cú pháp :
void free(void *ptr);
ptr: Con trỏ đến khối bộ nhớ cần giải phóng. Nếu ptr là NULL thì hàm free sẽ không làm gì
- 1 số nhiệm vụ và ứng dụng của Hàm ' free '
1.Giải phóng bộ nhớ
-
Giải phóng bộ nhớ của mảng con trỏ
-
Giải phóng bộ nhớ của các cấu trúc.
VI. Kết luận :
Quản lý bộ nhớ động là một phần quan trọng trong lập trình C nó giúp bạn tạo ra các chương trình linh hoạt và mượt mà, hiệu quả và tối ưu hóa việc sử dụng tài nguyên của hệ thống. Việc hiểu và sử dụng đúng các hàm quản lý bộ nhớ như malloc, calloc, realloc, và free là cơ sở để viết các chương trình ổn định và tránh các lỗi liên quan đến bộ nhớ.