Nội dung bài viết
Đăng ký học lập trình C++
Tại STDIO bạn được dạy nền tảng lập trình tốt nhất.
Đăng ký học
Cấp phát tĩnh và cấp phát động là hai cách cấp phát vùng nhớ trong C++ cũng như nhiều ngôn ngữ lập trình khác.

Giới thiệu

Khi chúng ta khai báo một biến hoặc một mảng, chúng ta cần cung cấp vùng nhớ cho chúng quản lý. Có hai cách cung cấp là cấp phát tĩnh và cấp phát động, chúng ta cần phân biệt và hiểu rõ chúng để sử dụng các vùng nhớ một cách hiệu quả hơn.

Tiền đề bài viết

Bài viết nằm trong chuỗi bài viết về Con trỏ trong Chương trình C++.

Đối tượng hướng đến

Những lập trình viên C++ đã thành thạo trong việc sử dụng biến, mảng và có kiến thức về con trỏ.

Cấp phát tĩnh

Đây là kiểu cấp phát thông dụng trong ngôn ngữ C++, là kiểu cấp phát mà chúng ta đã biết trong các bài học trước.

int a = 5;
int Arr[10];

Ta gọi Arr là mảng tĩnh. Cấp phát tĩnh sẽ lưu trữ toàn bộ giá trị của biến a và mảng Arr vào bộ nhớ Stack.

Lưu ý: khi khai báo mảng tĩnh, tham số ở trong cặp ngoặc vuông [ ] phải là một hằng số.

Cấp phát động

Đây là kiểu cấp phát thứ hai trong C++, là một kiểu cấp phát rất quan trọng, bất cứ lập trình viên C++ nào cũng phải thành thạo nó.

Khi sử dụng cấp phát động, chúng ta buộc phải sử dụng đến biến con trỏ và toán tử new

int *a = new int;
int n = 10;
int *Arr = new int[n]; 

Biến a là một biến con trỏ, chúng ta chỉ cho phép nó quản lý một vùng giá trị có kích thước như biến int thông thường. Khi muốn truy suất tới giá trị vùng nhớ đó ta sử dụng tới toán tử *

*a = 5;
cout << *a;

Ta gọi Arr là mảng động. Cấp phát động sẽ lưu trữ toàn bộ vùng nhớ mà a và Arr tham chiếu tới vào bộ nhớ Heap.

Ưu điểm

Có thể sử dụng biến làm tham số trong cặp ngoặc vuông [ ], ví dụ trên chúng ta sử dụng biến n. Do đó, chúng ta hoàn toàn có thể tính toán trước kích thước của mảng động trước khi cấp phát, tránh tình trạng lãng phí bộ nhớ. Hơn nữa chúng ta có thể truy xuất đến từng phần tử trong mảng bằng [ ] giống như trong cấp phát tĩnh

Arr[0] = 5;
Arr[1] = 10;
….

Cấp phát động lưu trữ vùng nhớ trong Heap, mà ta đã biết rằng, Heap là vùng nhớ động, nó có thể mở rộng cho đến hết RAM, nên chúng ta không cần lo lắng về sự thiếu bộ nhớ. Trong khi đối với Stack, kích thước của nó là cố định, dễ bị thiếu vùng nhớ hơn so với Heap, tuy nhiên cũng không cần quá lo lắng khi cấp phát tĩnh, trình biên dịch cung cấp cho chúng ta một vùng nhớ Stack với kích thước đủ sử dụng. Tôi đã kiểm tra thử bằng Visual Stdio 2013 thì thấy chúng ta có thể cấp phát tĩnh cho một mảng kiểu long với kích thước hơn 250000 phần tử.

Tuy nhiên cấp phát động cũng có một số nhược điểm. 

Khuyết điểm

Thứ nhất là khai báo phức tạp hơn cấp phát tĩnh. Thứ hai là bạn phải hoàn toàn kiểm soát được vùng nhớ động mà mình đang sử dụng, vì trình biên dịch không tự động thu hồi vùng nhớ như khi bạn sử dụng cấp phát tĩnh. Để làm được điều này chúng ta phải sử dụng đến toán tử delete

delete a;
delete[] Arr;

Toán tử delete cho phép ta thu hồi vùng nhớ đã được cấp phát, khi đó vùng nhớ đó sẽ trở thành vùng nhớ tự do, có thể dùng để cấp phát tiếp hoặc cho các process khác sử dụng. Bạn phải lưu ý sử dụng delete cho đúng cách, delete đối với vùng nhớ đơn và delete[] đối với mảng.

Bất cứ khi nào không có nhu cầu sử dụng đến vùng nhớ đã được cấp phát động, bạn nên phải giải phóng nó bằng toán tử delete để tránh sự lãng phí vùng nhớ đáng tiếc.

THẢO LUẬN