Xem thêm

Bộ nhớ động trong C/C++: Quản lí bộ nhớ linh hoạt và tiết kiệm thời gian

Huy Erick
Trong lập trình C++ và C, việc quản lí bộ nhớ để thao tác với dữ liệu trở nên tiện lợi, linh hoạt và tiết kiệm thời gian. Mảng, mặc dù hữu ích, nhưng có...

Trong lập trình C++ và C, việc quản lí bộ nhớ để thao tác với dữ liệu trở nên tiện lợi, linh hoạt và tiết kiệm thời gian. Mảng, mặc dù hữu ích, nhưng có kích thước cố định và không thể thay đổi trong quá trình chạy chương trình. Tuy nhiên, nếu chúng ta cần một lượng bộ nhớ có thể xác định ngay trong quá trình chạy chương trình mà không cần tạo ra một mảng với số lượng bất kỳ, có cách nào để làm điều này không? Giải pháp chính là sử dụng bộ nhớ động.

Bạn sẽ nắm được gì sau bài này?

  • Bộ nhớ động là gì?
  • Các hàm malloc, calloc, realloc và free trong C
  • Toán tử new, delete trong C++

Bộ nhớ động là gì?

Trong chương trình C++, chúng ta đã biết rằng có ba phân vùng bộ nhớ chính là Stack, Heap và Data/BSS. Phân vùng Stack được đặt tại vùng có địa chỉ cao nhất trong dãy bộ nhớ ảo và có dung lượng hạn chế. Với sự hạn chế về dung lượng bộ nhớ của phân vùng Stack, chúng ta sẽ gặp phải lỗi stack overflow nếu yêu cầu cấp phát vùng nhớ vượt quá dung lượng của phân vùng Stack. Để khắc phục hạn chế này, ta có thể sử dụng bộ nhớ động.

Từ "động" ở đây có nghĩa là "tự động". Bộ nhớ động cho phép ta cấp phát và thu hồi bộ nhớ theo nhu cầu của chương trình. Nó không giới hạn kích thước vùng nhớ cần cấp phát và không do chương trình quyết định việc cấp phát và thu hồi bộ nhớ. Trong chương trình C++, tất cả bộ nhớ động được xử lí thông qua hai toán tử quan trọng: new để cấp phát và delete để thu hồi.

Kỹ thuật cấp phát động trong C++

Toán tử new và new[]

Để có được bộ nhớ động, chúng ta có thể sử dụng toán tử new. Cú pháp của toán tử new như sau:

 *ptr = new ;

Hoặc, nếu muốn cấp phát một mảng:

 *ptr = new [kích_thước];

Ví dụ minh hoạ:

int *pA = new int; int *pB = new int[5];

Trong ví dụ trên, chúng ta có hai con trỏ pA và pB, và chúng ta đã cấp phát bộ nhớ động cho chúng. Mỗi con trỏ sẽ trỏ tới một vùng nhớ trên Heap được cấp phát tương ứng.

Kỹ thuật thu hồi bộ nhớ động trong C++

Để giải phóng bộ nhớ đã cấp phát, chúng ta sử dụng toán tử delete. Cú pháp của toán tử delete như sau:

delete ptr;

Hoặc, nếu muốn giải phóng một mảng:

delete[] ptr;

Ví dụ minh hoạ:

delete pA; delete[] pB;

Sau khi sử dụng delete, bộ nhớ trên Heap đã được giải phóng và các địa chỉ trên Heap có thể được sử dụng cho mục đích khác.

Kỹ thuật cấp phát động và thu hồi bộ nhớ động trong C

Tương tự như trong C++, trong ngôn ngữ C, chúng ta cũng có các hàm malloc, calloc, realloc và free để cấp phát và thu hồi bộ nhớ. Để sử dụng các hàm này, ta cần bao gồm thư viện stdlib.h hoặc alloc.h. Dưới đây là nguyên mẫu của các hàm này:

  • Hàm malloc:
void *malloc(size_t size);
  • Hàm calloc:
void *calloc(size_t num, size_t size);
  • Hàm realloc:
void *realloc(void *ptr, size_t size);
  • Hàm free:
void free(void *ptr);

Thắc mắc thường gặp:

  1. Sự khác biệt giữa hai hàm malloc và calloc?

Hai hàm này được sử dụng để cấp phát bộ nhớ động, nhưng có một sự khác biệt nhỏ. Hàm malloc chỉ cấp phát một vùng nhớ có kích thước giống như size, trong khi hàm calloc cấp phát và khởi tạo tất cả các giá trị của vùng nhớ mới thành 0.

  1. Tại sao có malloc, calloc rồi lại còn có realloc?

Hàm realloc được sử dụng để thay đổi kích thước của một vùng nhớ đã được cấp phát. Nếu không đủ vùng nhớ để cấp phát mới, vùng nhớ cũ không thay đổi. Nếu memblock là NULL, hàm realloc sẽ tương tự như hàm malloc và cấp phát một vùng nhớ mới. Kích thước mới cho vùng nhớ được cung cấp bởi tham số size, và nếu size bằng 0, vùng nhớ memblock sẽ được giải phóng.

Tổng kết:

Bộ nhớ động trong C/C++ giúp quản lí bộ nhớ linh hoạt và tiết kiệm thời gian. Chúng ta có thể sử dụng các toán tử new và delete trong C++, hoặc các hàm malloc, calloc, realloc và free trong C để cấp phát và thu hồi bộ nhớ động.

1